* Re: [PATCH] git-gui: fix browser with initial path
From: Bert Wesarg @ 2010-12-10 8:48 UTC (permalink / raw)
To: Pat Thoyts; +Cc: Bert Wesarg, Shawn O. Pearce, git
In-Reply-To: <1290497870-28673-1-git-send-email-bert.wesarg@googlemail.com>
Ping.
On Tue, Nov 23, 2010 at 08:37, Bert Wesarg <bert.wesarg@googlemail.com> wrote:
> The path given to the browser does not end in a slash, which results in bad
> path given to blame and broke [Up To Parent]. Also the path was not
> escaped before displaying.
>
> Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
>
> ---
> git-gui/lib/browser.tcl | 8 +++++++-
> 1 files changed, 7 insertions(+), 1 deletions(-)
>
> diff --git a/git-gui/lib/browser.tcl b/git-gui/lib/browser.tcl
> index c241572..a88a68b 100644
> --- a/git-gui/lib/browser.tcl
> +++ b/git-gui/lib/browser.tcl
> @@ -26,8 +26,14 @@ constructor new {commit {path {}}} {
> wm withdraw $top
> wm title $top [append "[appname] ([reponame]): " [mc "File Browser"]]
>
> + if {$path ne {}} {
> + if {[string index $path end] ne {/}} {
> + append path /
> + }
> + }
> +
> set browser_commit $commit
> - set browser_path $browser_commit:$path
> + set browser_path "$browser_commit:[escape_path $path]"
>
> ${NS}::label $w.path \
> -textvariable @browser_path \
> --
> tg: (6f10c41..) bw/git-gui/fix-browser-up (depends on: master)
>
^ permalink raw reply
* [RFC/PATCH 00/10] vcs-svn: prepare for (implement?) incremental import
From: Jonathan Nieder @ 2010-12-10 10:20 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
Hi,
Using David's "ls" command we can eliminate the in-memory repo_tree
and rely on the target repository for information about old revs.
This means all state that needs to persist between svn-fe runs is
either in the target repo or in the marks file, so in theory this
should allow incremental imports already (I haven't tried it).
Caveats:
Not split up as nicely as it ought to be. In particular, the last
patch should be split up at least into one patch to modify git
fast-import, another for the vcs-svn lib. Perhaps it could be split
finer than that.
There is a potential deadlock, marked with NEEDSWORK.
Error checking is not so great. Error states tend to result in
deadlock rather than a nicer error.
In particular, we have no way to distinguish between a missing
(nonsense) path and an empty directory.
There's a little blind alley in the first few patches --- cat_mark and
the function to apply deltas to an old rev do not survive to the end
of the series. I kept that because (1) I am lazy and (2) it serves as
a quick intro to use of the "ls" command.
Probably there are all sorts of bugs and unclear code. I haven't
tested beyond running the test suite.
You can find the series alone at
git://repo.or.cz/git/jrn.git refs/topics/db/vcs-svn-incremental
and merged with other topics at
git://repo.or.cz/git/jrn.git vcs-svn-pu
Requires the db/text-delta and db/fast-import-blob-access topics,
available from the same place.
Any thoughts would be welcome.
Jonathan Nieder (10):
vcs-svn: use higher mark numbers for blobs
vcs-svn: save marks for imported commits
vcs-svn: introduce cat_mark function to retrieve a marked blob
vcs-svn: make apply_delta caller retrieve preimage
vcs-svn: split off function to export result from delta application
vcs-svn: do not rely on marks for old blobs
vcs-svn: split off function to make 'ls' requests
vcs-svn: prepare to eliminate repo_tree structure
vcs-svn: simplifications for repo_modify_path et al
vcs-svn: eliminate repo_tree structure
cache.h | 2 +
fast-import.c | 42 +++++--
t/t9010-svn-fe.sh | 55 +++++----
vcs-svn/fast_export.c | 168 +++++++++++++++++++------
vcs-svn/fast_export.h | 22 +++-
vcs-svn/repo_tree.c | 333 ++++---------------------------------------------
vcs-svn/repo_tree.h | 6 +-
vcs-svn/string_pool.c | 2 +-
vcs-svn/string_pool.h | 2 +-
vcs-svn/svndump.c | 89 +++++++++----
10 files changed, 301 insertions(+), 420 deletions(-)
--
1.7.2.4
^ permalink raw reply
* [PATCH 01/10] vcs-svn: use higher mark numbers for blobs
From: Jonathan Nieder @ 2010-12-10 10:21 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
Prepare to use mark :5 for the commit corresponding to r5 (and so on).
1 billion seems sufficiently high for blob marks to avoid conflicting
with rev marks, while still leaving room for 3 billion blobs. Such
high mark numbers cause trouble with ancient fast-import versions, but
this topic cannot support git fast-import versions before 1.7.4 (which
introduces the cat-blob command) anyway.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
vcs-svn/repo_tree.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/vcs-svn/repo_tree.c b/vcs-svn/repo_tree.c
index eb55636..a4d8340 100644
--- a/vcs-svn/repo_tree.c
+++ b/vcs-svn/repo_tree.c
@@ -298,7 +298,7 @@ void repo_commit(uint32_t revision, uint32_t author, char *log, uint32_t uuid,
static void mark_init(void)
{
uint32_t i;
- mark = 0;
+ mark = 1024 * 1024 * 1024;
for (i = 0; i < dent_pool.size; i++)
if (!repo_dirent_is_dir(dent_pointer(i)) &&
dent_pointer(i)->content_offset > mark)
--
1.7.2.4
^ permalink raw reply related
* [PATCH 02/10] vcs-svn: save marks for imported commits
From: Jonathan Nieder @ 2010-12-10 10:22 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
vcs-svn/fast_export.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index e6ebdb8..093ce1d 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -61,6 +61,7 @@ void fast_export_commit(uint32_t revision, uint32_t author, char *log,
*gitsvnline = '\0';
}
printf("commit refs/heads/master\n");
+ printf("mark :%"PRIu32"\n", revision);
printf("committer %s <%s@%s> %ld +0000\n",
~author ? pool_fetch(author) : "nobody",
~author ? pool_fetch(author) : "nobody",
--
1.7.2.4
^ permalink raw reply related
* [PATCH 03/10] vcs-svn: introduce cat_mark function to retrieve a marked blob
From: Jonathan Nieder @ 2010-12-10 10:23 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
A blind alley. But it demonstrates how this works.
vcs-svn/fast_export.c | 23 +++++++++++++++--------
1 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index 093ce1d..daac201 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -116,6 +116,19 @@ static const char *get_response_line(void)
return response_line.buf;
}
+static off_t cat_mark(uint32_t mark)
+{
+ const char *response;
+ off_t length = length;
+
+ printf("cat-blob :%"PRIu32"\n", mark);
+ fflush(stdout);
+ response = get_response_line();
+ if (parse_cat_response_line(response, &length))
+ die("invalid cat-blob response: %s", response);
+ return length;
+}
+
static long apply_delta(uint32_t mark, off_t len, struct line_buffer *input,
uint32_t old_mark, uint32_t old_mode)
{
@@ -126,14 +139,8 @@ static long apply_delta(uint32_t mark, off_t len, struct line_buffer *input,
if (init_postimage() || !(out = buffer_tmpfile_rewind(&postimage)))
die("cannot open temporary file for blob retrieval");
- if (old_mark) {
- const char *response;
- printf("cat-blob :%"PRIu32"\n", old_mark);
- fflush(stdout);
- response = get_response_line();
- if (parse_cat_response_line(response, &preimage_len))
- die("invalid cat-blob response: %s", response);
- }
+ if (old_mark)
+ preimage_len = cat_mark(old_mark);
if (old_mode == REPO_MODE_LNK) {
strbuf_addstr(&preimage.buf, "link ");
preimage_len += strlen("link ");
--
1.7.2.4
^ permalink raw reply related
* [PATCH 04/10] vcs-svn: make apply_delta caller retrieve preimage
From: Jonathan Nieder @ 2010-12-10 10:23 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
The preimage argument to apply_delta is currently a mark, but some
callers might want to use a preimage named by sha1 or by revision
number and path instead. Let the caller take care of that.
The preimage_len argument represents the length of the preimage that
will appear followed by a newline in the REPORT_FD stream, or -1 to
just use an empty preimage. apply_delta is renamed to delta_apply so
callers that have not been updated can be detected at compile time.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
The special-cased behavior of -1 won't need to survive.
vcs-svn/fast_export.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index daac201..4168184 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -129,25 +129,23 @@ static off_t cat_mark(uint32_t mark)
return length;
}
-static long apply_delta(uint32_t mark, off_t len, struct line_buffer *input,
- uint32_t old_mark, uint32_t old_mode)
+static long delta_apply(uint32_t mark, off_t len, struct line_buffer *input,
+ off_t preimage_len, uint32_t old_mode)
{
long ret;
- off_t preimage_len = 0;
struct view preimage = {REPORT_FILENO, 0, STRBUF_INIT};
FILE *out;
if (init_postimage() || !(out = buffer_tmpfile_rewind(&postimage)))
die("cannot open temporary file for blob retrieval");
- if (old_mark)
- preimage_len = cat_mark(old_mark);
if (old_mode == REPO_MODE_LNK) {
strbuf_addstr(&preimage.buf, "link ");
- preimage_len += strlen("link ");
+ if (preimage_len >= 0)
+ preimage_len += strlen("link ");
}
if (svndiff0_apply(input, len, &preimage, out))
die("cannot apply delta");
- if (old_mark) {
+ if (preimage_len >= 0) {
/* Read the remainder of preimage and trailing newline. */
if (move_window(&preimage, preimage_len, 1))
die("cannot seek to end of input");
@@ -180,7 +178,9 @@ void fast_export_blob_delta(uint32_t mode, uint32_t mark,
long postimage_len;
if (len > maximum_signed_value_of_type(off_t))
die("enormous delta");
- postimage_len = apply_delta(mark, (off_t) len, input, old_mark, old_mode);
+ postimage_len = delta_apply(mark, (off_t) len, input,
+ old_mark ? cat_mark(old_mark) : -1,
+ old_mode);
if (mode == REPO_MODE_LNK) {
buffer_skip_bytes(&postimage, strlen("link "));
postimage_len -= strlen("link ");
--
1.7.2.4
^ permalink raw reply related
* [PATCH 05/10] vcs-svn: split off function to export result from delta application
From: Jonathan Nieder @ 2010-12-10 10:25 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
In this time of heavy experimentation, we will need multiple
fast_export_blob_delta variants. Make this easier by factoring
out the common part.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Also not needed, except perhaps as code cleanup.
vcs-svn/fast_export.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index 4168184..960b252 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -159,6 +159,18 @@ static long delta_apply(uint32_t mark, off_t len, struct line_buffer *input,
return ret;
}
+static void record_postimage(uint32_t mark, uint32_t mode,
+ long postimage_len)
+{
+ if (mode == REPO_MODE_LNK) {
+ buffer_skip_bytes(&postimage, strlen("link "));
+ postimage_len -= strlen("link ");
+ }
+ printf("blob\nmark :%"PRIu32"\ndata %ld\n", mark, postimage_len);
+ buffer_copy_bytes(&postimage, postimage_len);
+ fputc('\n', stdout);
+}
+
void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len, struct line_buffer *input)
{
if (mode == REPO_MODE_LNK) {
@@ -181,11 +193,5 @@ void fast_export_blob_delta(uint32_t mode, uint32_t mark,
postimage_len = delta_apply(mark, (off_t) len, input,
old_mark ? cat_mark(old_mark) : -1,
old_mode);
- if (mode == REPO_MODE_LNK) {
- buffer_skip_bytes(&postimage, strlen("link "));
- postimage_len -= strlen("link ");
- }
- printf("blob\nmark :%"PRIu32"\ndata %ld\n", mark, postimage_len);
- buffer_copy_bytes(&postimage, postimage_len);
- fputc('\n', stdout);
+ record_postimage(mark, mode, postimage_len);
}
--
1.7.2.4
^ permalink raw reply related
* [PATCH 06/10] vcs-svn: do not rely on marks for old blobs
From: Jonathan Nieder @ 2010-12-10 10:26 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
Retrieve old blobs by name and revision number from fast-import.
One step closer to bounded memory usage in svn-fe.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Superfluous except that it shows how to parse 'ls' responses.
A demo.
vcs-svn/fast_export.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++
vcs-svn/fast_export.h | 3 ++
vcs-svn/string_pool.c | 2 +-
vcs-svn/string_pool.h | 2 +-
vcs-svn/svndump.c | 6 +++++
5 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index 960b252..cca9810 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -88,6 +88,21 @@ static int ends_with(const char *s, size_t len, const char *suffix)
return !memcmp(s + len - suffixlen, suffix, suffixlen);
}
+static int parse_ls_response_line(const char *line, struct strbuf *objnam)
+{
+ const char *end = line + strlen(line);
+ const char *name, *tab;
+
+ if (end - line < strlen("100644 blob "))
+ return error("ls response too short: %s", line);
+ name = line + strlen("100644 blob ");
+ tab = memchr(name, '\t', end - name);
+ if (!tab)
+ return error("ls response does not contain tab: %s", line);
+ strbuf_add(objnam, name, tab - name);
+ return 0;
+}
+
static int parse_cat_response_line(const char *header, off_t *len)
{
size_t headerlen = strlen(header);
@@ -129,6 +144,31 @@ static off_t cat_mark(uint32_t mark)
return length;
}
+static off_t cat_from_rev(uint32_t rev, const uint32_t *path)
+{
+ const char *response;
+ off_t length = length;
+ struct strbuf blob_name = STRBUF_INIT;
+
+ /* ls :5 "path/to/old/file" */
+ printf("ls :%"PRIu32" \"", rev);
+ pool_print_seq(REPO_MAX_PATH_DEPTH, path, '/', stdout);
+ printf("\"\n");
+ fflush(stdout);
+
+ response = get_response_line();
+ if (parse_ls_response_line(response, &blob_name))
+ die("invalid ls response: %s", response);
+
+ printf("cat-blob %s\n", blob_name.buf);
+ fflush(stdout);
+ response = get_response_line();
+ if (parse_cat_response_line(response, &length))
+ die("invalid cat-blob response: %s", response);
+ strbuf_release(&blob_name);
+ return length;
+}
+
static long delta_apply(uint32_t mark, off_t len, struct line_buffer *input,
off_t preimage_len, uint32_t old_mode)
{
@@ -195,3 +235,16 @@ void fast_export_blob_delta(uint32_t mode, uint32_t mark,
old_mode);
record_postimage(mark, mode, postimage_len);
}
+
+void fast_export_blob_delta_rev(uint32_t mode, uint32_t mark, uint32_t old_mode,
+ uint32_t old_rev, const uint32_t *old_path,
+ uint32_t len, struct line_buffer *input)
+{
+ long postimage_len;
+ if (len > maximum_signed_value_of_type(off_t))
+ die("enormous delta");
+ postimage_len = delta_apply(mark, (off_t) len, input,
+ cat_from_rev(old_rev, old_path),
+ old_mode);
+ record_postimage(mark, mode, postimage_len);
+}
diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h
index 6f77c3b..487d3d4 100644
--- a/vcs-svn/fast_export.h
+++ b/vcs-svn/fast_export.h
@@ -13,5 +13,8 @@ void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len,
void fast_export_blob_delta(uint32_t mode, uint32_t mark,
uint32_t old_mode, uint32_t old_mark,
uint32_t len, struct line_buffer *input);
+void fast_export_blob_delta_rev(uint32_t mode, uint32_t mark, uint32_t old_mode,
+ uint32_t old_rev, const uint32_t *old_path,
+ uint32_t len, struct line_buffer *input);
#endif
diff --git a/vcs-svn/string_pool.c b/vcs-svn/string_pool.c
index f5b1da8..c08abac 100644
--- a/vcs-svn/string_pool.c
+++ b/vcs-svn/string_pool.c
@@ -65,7 +65,7 @@ uint32_t pool_tok_r(char *str, const char *delim, char **saveptr)
return token ? pool_intern(token) : ~0;
}
-void pool_print_seq(uint32_t len, uint32_t *seq, char delim, FILE *stream)
+void pool_print_seq(uint32_t len, const uint32_t *seq, char delim, FILE *stream)
{
uint32_t i;
for (i = 0; i < len && ~seq[i]; i++) {
diff --git a/vcs-svn/string_pool.h b/vcs-svn/string_pool.h
index 222fb66..3720cf8 100644
--- a/vcs-svn/string_pool.h
+++ b/vcs-svn/string_pool.h
@@ -4,7 +4,7 @@
uint32_t pool_intern(const char *key);
const char *pool_fetch(uint32_t entry);
uint32_t pool_tok_r(char *str, const char *delim, char **saveptr);
-void pool_print_seq(uint32_t len, uint32_t *seq, char delim, FILE *stream);
+void pool_print_seq(uint32_t len, const uint32_t *seq, char delim, FILE *stream);
uint32_t pool_tok_seq(uint32_t sz, uint32_t *seq, const char *delim, char *str);
void pool_reset(void);
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index c6d6337..da968fa 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c
@@ -259,6 +259,12 @@ static void handle_node(void)
fast_export_blob(node_ctx.type, mark, node_ctx.textLength, &input);
return;
}
+ if (node_ctx.srcRev) {
+ fast_export_blob_delta_rev(node_ctx.type, mark, old_mode,
+ node_ctx.srcRev, node_ctx.src,
+ node_ctx.textLength, &input);
+ return;
+ }
fast_export_blob_delta(node_ctx.type, mark, old_mode, old_mark,
node_ctx.textLength, &input);
}
--
1.7.2.4
^ permalink raw reply related
* [PATCH 07/10] vcs-svn: split off function to make 'ls' requests
From: Jonathan Nieder @ 2010-12-10 10:27 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
ls_from_rev will survive; cat_from_rev will not.
vcs-svn/fast_export.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index cca9810..6a4a689 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -80,6 +80,15 @@ void fast_export_commit(uint32_t revision, uint32_t author, char *log,
printf("progress Imported commit %"PRIu32".\n\n", revision);
}
+static void ls_from_rev(uint32_t rev, const uint32_t *path)
+{
+ /* ls :5 "path/to/old/file" */
+ printf("ls :%"PRIu32" \"", rev);
+ pool_print_seq(REPO_MAX_PATH_DEPTH, path, '/', stdout);
+ printf("\"\n");
+ fflush(stdout);
+}
+
static int ends_with(const char *s, size_t len, const char *suffix)
{
const size_t suffixlen = strlen(suffix);
@@ -150,12 +159,7 @@ static off_t cat_from_rev(uint32_t rev, const uint32_t *path)
off_t length = length;
struct strbuf blob_name = STRBUF_INIT;
- /* ls :5 "path/to/old/file" */
- printf("ls :%"PRIu32" \"", rev);
- pool_print_seq(REPO_MAX_PATH_DEPTH, path, '/', stdout);
- printf("\"\n");
- fflush(stdout);
-
+ ls_from_rev(rev, path);
response = get_response_line();
if (parse_ls_response_line(response, &blob_name))
die("invalid ls response: %s", response);
--
1.7.2.4
^ permalink raw reply related
* [PATCH 08/10] vcs-svn: prepare to eliminate repo_tree structure
From: Jonathan Nieder @ 2010-12-10 10:28 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
Currently svn-fe processes each commit in two stages: first decide
on the correct content for all paths and export the relevant blobs,
then export a commit with the result.
But we can keep less state and simplify svn-fe a great deal by
doing exporting the commit in one stage: use 'inline' blobs for
each path and remember nothing. This way, the repo_tree structure
could be eliminated, and we would get support for incremental
imports 'for free'.
Reorganize handle_node() along these lines. This is just a code
cleanup; the functional change to repo_tree will come later.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
vcs-svn/svndump.c | 32 +++++++++++++++++++++++---------
1 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index da968fa..649a468 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c
@@ -201,11 +201,12 @@ static void handle_node(void)
uint32_t mark = 0, old_mode, old_mark;
const uint32_t type = node_ctx.type;
const int have_props = node_ctx.propLength != LENGTH_UNKNOWN;
+ const int have_text = node_ctx.textLength != LENGTH_UNKNOWN;
- if (node_ctx.textLength != LENGTH_UNKNOWN)
+ if (have_text)
mark = next_blob_mark();
if (node_ctx.action == NODEACT_DELETE) {
- if (mark || have_props || node_ctx.srcRev)
+ if (have_text || have_props || node_ctx.srcRev)
die("invalid dump: deletion node has "
"copyfrom info, text, or properties");
return repo_delete(node_ctx.dst);
@@ -219,8 +220,13 @@ static void handle_node(void)
if (node_ctx.action == NODEACT_ADD)
node_ctx.action = NODEACT_CHANGE;
}
- if (mark && type == REPO_MODE_DIR)
+ if (have_text && type == REPO_MODE_DIR)
die("invalid dump: directories cannot have text attached");
+
+ /*
+ * Find old content (old_mark) and decide on the new content (mark)
+ * and mode (node_ctx.type).
+ */
if (node_ctx.action == NODEACT_CHANGE && !~*node_ctx.dst) {
if (type != REPO_MODE_DIR)
die("invalid dump: root of tree is not a regular file");
@@ -228,7 +234,9 @@ static void handle_node(void)
} else if (node_ctx.action == NODEACT_CHANGE) {
uint32_t mode;
old_mark = repo_read_path(node_ctx.dst);
- mode = repo_modify_path(node_ctx.dst, 0, mark);
+ if (!have_text)
+ mark = old_mark;
+ mode = repo_modify_path(node_ctx.dst, 0, 0);
if (!mode)
die("invalid dump: path to be modified is missing");
if (mode == REPO_MODE_DIR && type != REPO_MODE_DIR)
@@ -237,23 +245,29 @@ static void handle_node(void)
die("invalid dump: cannot modify a file into a directory");
node_ctx.type = mode;
} else if (node_ctx.action == NODEACT_ADD) {
- if (!mark && type != REPO_MODE_DIR)
+ if (!have_text && type != REPO_MODE_DIR)
die("invalid dump: adds node without text");
- repo_add(node_ctx.dst, type, mark);
old_mark = 0;
} else {
die("invalid dump: Node-path block lacks Node-action");
}
+
+ /*
+ * Adjust mode to reflect properties.
+ */
old_mode = node_ctx.type;
if (have_props) {
if (!node_ctx.prop_delta)
node_ctx.type = type;
if (node_ctx.propLength)
read_props();
- if (node_ctx.type != old_mode)
- repo_modify_path(node_ctx.dst, node_ctx.type, mark);
}
- if (!mark)
+
+ /*
+ * Save the result.
+ */
+ repo_add(node_ctx.dst, node_ctx.type, mark);
+ if (!have_text)
return;
if (!node_ctx.text_delta) {
fast_export_blob(node_ctx.type, mark, node_ctx.textLength, &input);
--
1.7.2.4
^ permalink raw reply related
* [PATCH 09/10] vcs-svn: simplifications for repo_modify_path et al
From: Jonathan Nieder @ 2010-12-10 10:30 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
Restrict repo_modify_path API to functions that are actually
needed. That is:
- decouple reading the mode and content of dirents from
other operations
- remove repo_modify_path. It was only used to read the
mode from dirents.
- remove the ability to use repo_read_mode on a missing
path. The existing code only errored out in that case,
anyway.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
vcs-svn/repo_tree.c | 25 +++++++++----------------
vcs-svn/repo_tree.h | 4 ++--
vcs-svn/svndump.c | 4 +---
3 files changed, 12 insertions(+), 21 deletions(-)
diff --git a/vcs-svn/repo_tree.c b/vcs-svn/repo_tree.c
index a4d8340..4d98185 100644
--- a/vcs-svn/repo_tree.c
+++ b/vcs-svn/repo_tree.c
@@ -166,7 +166,15 @@ uint32_t repo_read_path(uint32_t *path)
return content_offset;
}
-uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst)
+uint32_t repo_read_mode(const uint32_t *path)
+{
+ struct repo_dirent *dent = repo_read_dirent(active_commit, path);
+ if (dent == NULL)
+ die("invalid dump: path to be modified is missing");
+ return dent->mode;
+}
+
+void repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst)
{
uint32_t mode = 0, content_offset = 0;
struct repo_dirent *src_dent;
@@ -176,7 +184,6 @@ uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst)
content_offset = src_dent->content_offset;
repo_write_dirent(dst, mode, content_offset, 0);
}
- return mode;
}
void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark)
@@ -184,20 +191,6 @@ void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark)
repo_write_dirent(path, mode, blob_mark, 0);
}
-uint32_t repo_modify_path(uint32_t *path, uint32_t mode, uint32_t blob_mark)
-{
- struct repo_dirent *src_dent;
- src_dent = repo_read_dirent(active_commit, path);
- if (!src_dent)
- return 0;
- if (!blob_mark)
- blob_mark = src_dent->content_offset;
- if (!mode)
- mode = src_dent->mode;
- repo_write_dirent(path, mode, blob_mark, 0);
- return mode;
-}
-
void repo_delete(uint32_t *path)
{
repo_write_dirent(path, 0, 0, 1);
diff --git a/vcs-svn/repo_tree.h b/vcs-svn/repo_tree.h
index 7070839..0499a19 100644
--- a/vcs-svn/repo_tree.h
+++ b/vcs-svn/repo_tree.h
@@ -12,10 +12,10 @@
#define REPO_MAX_PATH_DEPTH 1000
uint32_t next_blob_mark(void);
-uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst);
+void repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst);
void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark);
-uint32_t repo_modify_path(uint32_t *path, uint32_t mode, uint32_t blob_mark);
uint32_t repo_read_path(uint32_t *path);
+uint32_t repo_read_mode(const uint32_t *path);
void repo_delete(uint32_t *path);
void repo_commit(uint32_t revision, uint32_t author, char *log, uint32_t uuid,
uint32_t url, long unsigned timestamp);
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index 649a468..31c6056 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c
@@ -236,9 +236,7 @@ static void handle_node(void)
old_mark = repo_read_path(node_ctx.dst);
if (!have_text)
mark = old_mark;
- mode = repo_modify_path(node_ctx.dst, 0, 0);
- if (!mode)
- die("invalid dump: path to be modified is missing");
+ mode = repo_read_mode(node_ctx.dst);
if (mode == REPO_MODE_DIR && type != REPO_MODE_DIR)
die("invalid dump: cannot modify a directory into a file");
if (mode != REPO_MODE_DIR && type == REPO_MODE_DIR)
--
1.7.2.4
^ permalink raw reply related
* [PATCH 10/10] vcs-svn: eliminate repo_tree structure
From: Jonathan Nieder @ 2010-12-10 10:33 UTC (permalink / raw)
To: git
Cc: David Barr, Ramkumar Ramachandra, Sverre Rabbelier, Sam Vilain,
Stephen Bash, Tomas Carnecky
In-Reply-To: <20101210102007.GA26298@burratino>
Rely on fast-import for information about previous revs.
This requires always setting up backward flow of information,
even for v2 dumps. On the plus side, it simplifies the code
by quite a bit and opens the door to further simplifications.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
That's the end of the series. Sorry for its rough state; just thought
it would be useful to get this out early so other tools can be built
on it. No doubt it is terribly buggy and ugly. Reports of both sorts
of problem would be greatly appreciated.
cache.h | 2 +
fast-import.c | 42 +++++--
t/t9010-svn-fe.sh | 55 +++++----
vcs-svn/fast_export.c | 173 +++++++++++++++------------
vcs-svn/fast_export.h | 25 +++--
vcs-svn/repo_tree.c | 310 +++----------------------------------------------
vcs-svn/repo_tree.h | 2 +-
vcs-svn/svndump.c | 73 +++++++-----
8 files changed, 239 insertions(+), 443 deletions(-)
diff --git a/cache.h b/cache.h
index 33decd9..33e69eb 100644
--- a/cache.h
+++ b/cache.h
@@ -678,6 +678,8 @@ static inline void hashclr(unsigned char *hash)
#define EMPTY_TREE_SHA1_BIN \
"\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
"\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
+#define EMPTY_BLOB_SHA1_HEX \
+ "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
int git_mkstemp(char *path, size_t n, const char *template);
diff --git a/fast-import.c b/fast-import.c
index 670f4f5..e62f34d 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -2862,12 +2862,20 @@ static struct object_entry *parse_treeish_dataref(const char **r)
static void print_ls(int mode, unsigned char *sha1, char *path)
{
- enum object_type type;
struct strbuf line = STRBUF_INIT;
- type = sha1_object_info(sha1, NULL);
+ const char *type;
+
+ /* See show_tree(). */
+ if (S_ISGITLINK(mode))
+ type = commit_type;
+ else if (S_ISDIR(mode))
+ type = tree_type;
+ else
+ type = blob_type;
+
/* mode SP type SP object_name TAB path LF */
- strbuf_addf(&line, "%o %s %s\t%s\n",
- mode, typename(type), sha1_to_hex(sha1), path);
+ strbuf_addf(&line, "%06o %s %s\t%s\n",
+ mode, type, sha1_to_hex(sha1), path);
cat_blob_write(line.buf, line.len);
strbuf_release(&line);
}
@@ -2898,17 +2906,25 @@ static void parse_ls(struct branch *b)
if (*p)
die("Garbage after path: %s", command_buf.buf);
tree_content_get(root, uq.buf, &leaf);
- if (!leaf.versions[1].mode)
- die("Path %s not in branch", uq.buf);
+ if (!leaf.versions[1].mode) {
+ /*
+ * NEEDSWORK. Missing path? Must be an empty directory!
+ *
+ * Should find a nicer way to report this --- e.g.
+ * die("Path %s not in branch", uq.buf);
+ */
+ print_ls(S_IFDIR, (unsigned char *) EMPTY_TREE_SHA1_BIN, uq.buf);
+ } else {
+ /*
+ * A directory in preparation would have a sha1 of zero
+ * until it is saved. Save, for simplicity.
+ */
+ if (S_ISDIR(leaf.versions[1].mode))
+ store_tree(&leaf);
- /*
- * A directory in preparation would have a sha1 of zero
- * until it is saved. Save, for simplicity.
- */
- if (S_ISDIR(leaf.versions[1].mode))
- store_tree(&leaf);
+ print_ls(leaf.versions[1].mode, leaf.versions[1].sha1, uq.buf);
+ }
- print_ls(leaf.versions[1].mode, leaf.versions[1].sha1, uq.buf);
strbuf_release(&uq);
if (!b || root != &b->branch_tree)
release_tree_entry(root);
diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
index 022e3e3..34bb9f6 100755
--- a/t/t9010-svn-fe.sh
+++ b/t/t9010-svn-fe.sh
@@ -53,8 +53,7 @@ test_expect_success 'empty dump' '
test_expect_success 'v4 dumps not supported' '
reinit_git &&
echo "SVN-fs-dump-format-version: 4" >v4.dump &&
- test_must_fail test-svn-fe v4.dump >stream &&
- test_cmp empty stream
+ test_must_fail test-svn-fe v4.dump
'
test_expect_failure 'empty revision' '
@@ -301,8 +300,9 @@ test_expect_success 'action: add node without text' '
test_must_fail test-svn-fe textless.dump
'
-test_expect_failure 'change file mode but keep old content' '
+test_expect_failure PIPE 'change file mode but keep old content' '
reinit_git &&
+ rm -f backflow &&
cat >expect <<-\EOF &&
OBJID
:120000 100644 OBJID OBJID T greeting
@@ -364,8 +364,9 @@ test_expect_failure 'change file mode but keep old content' '
PROPS-END
EOF
- test-svn-fe filemode.dump >stream &&
- git fast-import <stream &&
+ mkfifo backflow &&
+ test-svn-fe filemode.dump 3<backflow |
+ git fast-import --cat-blob-fd=3 3>backflow &&
{
git rev-list HEAD |
git diff-tree --root --stdin |
@@ -378,8 +379,9 @@ test_expect_failure 'change file mode but keep old content' '
test_cmp hello actual.target
'
-test_expect_success 'change file mode and reiterate content' '
+test_expect_success PIPE 'change file mode and reiterate content' '
reinit_git &&
+ rm -f backflow &&
cat >expect <<-\EOF &&
OBJID
:120000 100644 OBJID OBJID T greeting
@@ -390,7 +392,7 @@ test_expect_success 'change file mode and reiterate content' '
EOF
echo "link hello" >expect.blob &&
echo hello >hello &&
- cat >filemode.dump <<-\EOF &&
+ cat >filemode2.dump <<-\EOF &&
SVN-fs-dump-format-version: 3
Revision-number: 1
@@ -445,8 +447,9 @@ test_expect_success 'change file mode and reiterate content' '
PROPS-END
link hello
EOF
- test-svn-fe filemode.dump >stream &&
- git fast-import <stream &&
+ mkfifo backflow &&
+ test-svn-fe filemode2.dump 3<backflow |
+ git fast-import --cat-blob-fd=3 3>backflow &&
{
git rev-list HEAD |
git diff-tree --root --stdin |
@@ -522,12 +525,13 @@ test_expect_success PIPE 'deltas supported' '
cat delta
} >delta.dump &&
mkfifo backflow &&
- test_must_fail test-svn-fe delta.dump 3<backflow |
+ test-svn-fe delta.dump 3<backflow |
git fast-import --cat-blob-fd=3 3>backflow
'
-test_expect_success 'property deltas supported' '
+test_expect_success PIPE 'property deltas supported' '
reinit_git &&
+ rm -f backflow &&
cat >expect <<-\EOF &&
OBJID
:100755 100644 OBJID OBJID M script.sh
@@ -582,8 +586,9 @@ test_expect_success 'property deltas supported' '
PROPS-END
EOF
} >propdelta.dump &&
- test-svn-fe propdelta.dump >stream &&
- git fast-import <stream &&
+ mkfifo backflow &&
+ test-svn-fe propdelta.dump 3<backflow |
+ git fast-import --cat-blob-fd=3 3>backflow &&
{
git rev-list HEAD |
git diff-tree --stdin |
@@ -592,8 +597,9 @@ test_expect_success 'property deltas supported' '
test_cmp expect actual
'
-test_expect_success 'properties on /' '
+test_expect_success PIPE 'properties on /' '
reinit_git &&
+ rm -f backflow &&
cat <<-\EOF >expect &&
OBJID
OBJID
@@ -637,8 +643,9 @@ test_expect_success 'properties on /' '
PROPS-END
EOF
- test-svn-fe changeroot.dump >stream &&
- git fast-import <stream &&
+ mkfifo backflow &&
+ test-svn-fe changeroot.dump 3<backflow |
+ git fast-import --cat-blob-fd=3 3>backflow &&
{
git rev-list HEAD |
git diff-tree --root --always --stdin |
@@ -647,8 +654,9 @@ test_expect_success 'properties on /' '
test_cmp expect actual
'
-test_expect_success 'deltas for typechange' '
+test_expect_success PIPE 'deltas for typechange' '
reinit_git &&
+ rm -f backflow &&
cat >expect <<-\EOF &&
OBJID
:120000 100644 OBJID OBJID T test-file
@@ -723,8 +731,9 @@ test_expect_success 'deltas for typechange' '
PROPS-END
link testing 321
EOF
- test-svn-fe deleteprop.dump >stream &&
- git fast-import <stream &&
+ mkfifo backflow &&
+ test-svn-fe deleteprop.dump 3<backflow |
+ git fast-import --cat-blob-fd=3 3>backflow &&
{
git rev-list HEAD |
git diff-tree --root --stdin |
@@ -841,15 +850,17 @@ test_expect_success PIPE 'deltas need not consume the whole preimage' '
test_cmp expect.3 actual.3
'
-test_expect_success 't9135/svn.dump' '
+test_expect_success PIPE 't9135/svn.dump' '
+ rm -f backflow &&
svnadmin create simple-svn &&
svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
svn_cmd export "file://$PWD/simple-svn" simple-svnco &&
git init simple-git &&
- test-svn-fe "$TEST_DIRECTORY/t9135/svn.dump" >simple.fe &&
+ mkfifo backflow &&
+ test-svn-fe "$TEST_DIRECTORY/t9135/svn.dump" 3<backflow |
(
cd simple-git &&
- git fast-import <../simple.fe
+ git fast-import --cat-blob-fd=3 3>../backflow
) &&
(
cd simple-svnco &&
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index 6a4a689..96f6023 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -37,17 +37,17 @@ void fast_export_delete(uint32_t depth, uint32_t *path)
putchar('\n');
}
-void fast_export_modify(uint32_t depth, uint32_t *path, uint32_t mode,
- uint32_t mark)
+void fast_export_modify(uint32_t depth, const uint32_t *path, uint32_t mode,
+ const char *dataref)
{
/* Mode must be 100644, 100755, 120000, or 160000. */
- printf("M %06"PRIo32" :%"PRIu32" ", mode, mark);
+ printf("M %06"PRIo32" %s ", mode, dataref);
pool_print_seq(depth, path, '/', stdout);
putchar('\n');
}
static char gitsvnline[MAX_GITSVN_LINE_LEN];
-void fast_export_commit(uint32_t revision, uint32_t author, char *log,
+void fast_export_begin_commit(uint32_t revision, uint32_t author, char *log,
uint32_t uuid, uint32_t url,
unsigned long timestamp)
{
@@ -74,10 +74,20 @@ void fast_export_commit(uint32_t revision, uint32_t author, char *log,
printf("from refs/heads/master^0\n");
first_commit_done = 1;
}
- repo_diff(revision - 1, revision);
- fputc('\n', stdout);
+}
- printf("progress Imported commit %"PRIu32".\n\n", revision);
+void fast_export_end_commit(uint32_t revision)
+{
+ printf("\nprogress Imported commit %"PRIu32".\n\n", revision);
+}
+
+static struct strbuf response_line = STRBUF_INIT;
+static const char *get_response_line(void)
+{
+ strbuf_reset(&response_line);
+ if (fd_read_line(&response_line, REPORT_FILENO))
+ return NULL;
+ return response_line.buf;
}
static void ls_from_rev(uint32_t rev, const uint32_t *path)
@@ -89,6 +99,56 @@ static void ls_from_rev(uint32_t rev, const uint32_t *path)
fflush(stdout);
}
+static void parse_ls_response(const char *response, uint32_t *mode,
+ struct strbuf *dataref)
+{
+ const char *tab;
+ const char *response_end;
+
+ if (!response)
+ die("cannot read ls response");
+ response_end = response + strlen(response);
+
+ /* Mode. */
+ if (response_end - response < strlen("100644") ||
+ response[strlen("100644")] != ' ')
+ die("invalid ls response: missing mode: %s", response);
+ *mode = 0;
+ for (; *response != ' '; response++) {
+ *mode *= 8;
+ *mode += (*response - '0');
+ }
+
+ /* ' blob ' or ' tree ' */
+ if (response_end - response < strlen(" blob "))
+ die("invalid ls response: missing type: %s", response);
+ response += strlen(" blob ");
+
+ /* Dataref. */
+ tab = memchr(response, '\t', response_end - response);
+ if (!tab)
+ die("invalid ls response: missing tab: %s", response);
+ strbuf_add(dataref, response, tab - response);
+}
+
+void fast_export_ls_rev(uint32_t rev, const uint32_t *path,
+ uint32_t *mode, struct strbuf *dataref)
+{
+ ls_from_rev(rev, path);
+ parse_ls_response(get_response_line(), mode, dataref);
+}
+
+/* Read directory entry from the active commit. */
+void fast_export_ls(const uint32_t *path,
+ uint32_t *mode, struct strbuf *dataref)
+{
+ printf("ls \"");
+ pool_print_seq(REPO_MAX_PATH_DEPTH, path, '/', stdout);
+ printf("\"\n");
+ fflush(stdout);
+ parse_ls_response(get_response_line(), mode, dataref);
+}
+
static int ends_with(const char *s, size_t len, const char *suffix)
{
const size_t suffixlen = strlen(suffix);
@@ -97,27 +157,15 @@ static int ends_with(const char *s, size_t len, const char *suffix)
return !memcmp(s + len - suffixlen, suffix, suffixlen);
}
-static int parse_ls_response_line(const char *line, struct strbuf *objnam)
-{
- const char *end = line + strlen(line);
- const char *name, *tab;
-
- if (end - line < strlen("100644 blob "))
- return error("ls response too short: %s", line);
- name = line + strlen("100644 blob ");
- tab = memchr(name, '\t', end - name);
- if (!tab)
- return error("ls response does not contain tab: %s", line);
- strbuf_add(objnam, name, tab - name);
- return 0;
-}
-
static int parse_cat_response_line(const char *header, off_t *len)
{
- size_t headerlen = strlen(header);
+ size_t headerlen;
const char *type;
const char *end;
+ if (!header)
+ return error("missing cat-blob response");
+ headerlen = strlen(header);
if (ends_with(header, headerlen, " missing"))
return error("cat-blob reports missing blob: %s", header);
type = memmem(header, headerlen, " blob ", strlen(" blob "));
@@ -131,49 +179,22 @@ static int parse_cat_response_line(const char *header, off_t *len)
return 0;
}
-static struct strbuf response_line = STRBUF_INIT;
-static const char *get_response_line(void)
+static off_t cat_dataref(const char *dataref)
{
- strbuf_reset(&response_line);
- if (fd_read_line(&response_line, REPORT_FILENO))
- return NULL;
- return response_line.buf;
-}
-
-static off_t cat_mark(uint32_t mark)
-{
- const char *response;
off_t length = length;
-
- printf("cat-blob :%"PRIu32"\n", mark);
- fflush(stdout);
- response = get_response_line();
- if (parse_cat_response_line(response, &length))
- die("invalid cat-blob response: %s", response);
- return length;
-}
-
-static off_t cat_from_rev(uint32_t rev, const uint32_t *path)
-{
const char *response;
- off_t length = length;
- struct strbuf blob_name = STRBUF_INIT;
-
- ls_from_rev(rev, path);
- response = get_response_line();
- if (parse_ls_response_line(response, &blob_name))
- die("invalid ls response: %s", response);
- printf("cat-blob %s\n", blob_name.buf);
+ if (!dataref)
+ die("BUG: null data reference");
+ printf("cat-blob %s\n", dataref);
fflush(stdout);
response = get_response_line();
if (parse_cat_response_line(response, &length))
- die("invalid cat-blob response: %s", response);
- strbuf_release(&blob_name);
+ die("invalid cat-blob response");
return length;
}
-static long delta_apply(uint32_t mark, off_t len, struct line_buffer *input,
+static long delta_apply(off_t len, struct line_buffer *input,
off_t preimage_len, uint32_t old_mode)
{
long ret;
@@ -203,52 +224,50 @@ static long delta_apply(uint32_t mark, off_t len, struct line_buffer *input,
return ret;
}
-static void record_postimage(uint32_t mark, uint32_t mode,
- long postimage_len)
+static void record_postimage(uint32_t mode, long postimage_len)
{
if (mode == REPO_MODE_LNK) {
buffer_skip_bytes(&postimage, strlen("link "));
postimage_len -= strlen("link ");
}
- printf("blob\nmark :%"PRIu32"\ndata %ld\n", mark, postimage_len);
+ printf("data %ld\n", postimage_len);
buffer_copy_bytes(&postimage, postimage_len);
fputc('\n', stdout);
}
-void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len, struct line_buffer *input)
+void fast_export_data(uint32_t mode, uint32_t len, struct line_buffer *input)
{
if (mode == REPO_MODE_LNK) {
/* svn symlink blobs start with "link " */
buffer_skip_bytes(input, 5);
len -= 5;
}
- printf("blob\nmark :%"PRIu32"\ndata %"PRIu32"\n", mark, len);
+ printf("data %"PRIu32"\n", len);
buffer_copy_bytes(input, len);
fputc('\n', stdout);
}
-void fast_export_blob_delta(uint32_t mode, uint32_t mark,
- uint32_t old_mode, uint32_t old_mark,
- uint32_t len, struct line_buffer *input)
+void fast_export_empty_blob(void)
{
- long postimage_len;
- if (len > maximum_signed_value_of_type(off_t))
- die("enormous delta");
- postimage_len = delta_apply(mark, (off_t) len, input,
- old_mark ? cat_mark(old_mark) : -1,
- old_mode);
- record_postimage(mark, mode, postimage_len);
+ printf("blob\ndata 0\n\n");
}
-void fast_export_blob_delta_rev(uint32_t mode, uint32_t mark, uint32_t old_mode,
- uint32_t old_rev, const uint32_t *old_path,
+void fast_export_delta(const uint32_t *path, uint32_t mode, uint32_t old_mode,
+ const char *dataref,
uint32_t len, struct line_buffer *input)
{
+ off_t preimage_len;
long postimage_len;
if (len > maximum_signed_value_of_type(off_t))
die("enormous delta");
- postimage_len = delta_apply(mark, (off_t) len, input,
- cat_from_rev(old_rev, old_path),
- old_mode);
- record_postimage(mark, mode, postimage_len);
+ preimage_len = cat_dataref(dataref);
+
+ /*
+ * NEEDSWORK: Will deadlock with very long paths.
+ */
+ fast_export_modify(REPO_MAX_PATH_DEPTH, path, mode, "inline");
+
+ postimage_len = delta_apply((off_t) len, input,
+ preimage_len, old_mode);
+ record_postimage(mode, postimage_len);
}
diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h
index 487d3d4..8415d2c 100644
--- a/vcs-svn/fast_export.h
+++ b/vcs-svn/fast_export.h
@@ -3,18 +3,23 @@
#include "line_buffer.h"
+/* Output routines */
void fast_export_delete(uint32_t depth, uint32_t *path);
-void fast_export_modify(uint32_t depth, uint32_t *path, uint32_t mode,
- uint32_t mark);
-void fast_export_commit(uint32_t revision, uint32_t author, char *log,
+void fast_export_modify(uint32_t depth, const uint32_t *path, uint32_t mode,
+ const char *dataref);
+void fast_export_begin_commit(uint32_t revision, uint32_t author, char *log,
uint32_t uuid, uint32_t url, unsigned long timestamp);
-void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len,
- struct line_buffer *input);
-void fast_export_blob_delta(uint32_t mode, uint32_t mark,
- uint32_t old_mode, uint32_t old_mark,
- uint32_t len, struct line_buffer *input);
-void fast_export_blob_delta_rev(uint32_t mode, uint32_t mark, uint32_t old_mode,
- uint32_t old_rev, const uint32_t *old_path,
+void fast_export_end_commit(uint32_t revision);
+void fast_export_empty_blob(void);
+void fast_export_data(uint32_t mode, uint32_t len, struct line_buffer *input);
+void fast_export_delta(const uint32_t *path, uint32_t mode, uint32_t old_mode,
+ const char *dataref,
uint32_t len, struct line_buffer *input);
+/* Input routines */
+void fast_export_ls_rev(uint32_t rev, const uint32_t *path,
+ uint32_t *mode_out, struct strbuf *dataref_out);
+void fast_export_ls(const uint32_t *path,
+ uint32_t *mode_out, struct strbuf *dataref_out);
+
#endif
diff --git a/vcs-svn/repo_tree.c b/vcs-svn/repo_tree.c
index 4d98185..1283089 100644
--- a/vcs-svn/repo_tree.c
+++ b/vcs-svn/repo_tree.c
@@ -4,321 +4,49 @@
*/
#include "git-compat-util.h"
-
-#include "string_pool.h"
+#include "strbuf.h"
#include "repo_tree.h"
-#include "obj_pool.h"
#include "fast_export.h"
-#include "trp.h"
-
-struct repo_dirent {
- uint32_t name_offset;
- struct trp_node children;
- uint32_t mode;
- uint32_t content_offset;
-};
-
-struct repo_dir {
- struct trp_root entries;
-};
-
-struct repo_commit {
- uint32_t root_dir_offset;
-};
-
-/* Memory pools for commit, dir and dirent */
-obj_pool_gen(commit, struct repo_commit, 4096)
-obj_pool_gen(dir, struct repo_dir, 4096)
-obj_pool_gen(dent, struct repo_dirent, 4096)
-
-static uint32_t active_commit;
-static uint32_t mark;
-
-static int repo_dirent_name_cmp(const void *a, const void *b);
-
-/* Treap for directory entries */
-trp_gen(static, dent_, struct repo_dirent, children, dent, repo_dirent_name_cmp);
-
-uint32_t next_blob_mark(void)
-{
- return mark++;
-}
-
-static struct repo_dir *repo_commit_root_dir(struct repo_commit *commit)
-{
- return dir_pointer(commit->root_dir_offset);
-}
-
-static struct repo_dirent *repo_first_dirent(struct repo_dir *dir)
-{
- return dent_first(&dir->entries);
-}
-
-static int repo_dirent_name_cmp(const void *a, const void *b)
-{
- const struct repo_dirent *dent1 = a, *dent2 = b;
- uint32_t a_offset = dent1->name_offset;
- uint32_t b_offset = dent2->name_offset;
- return (a_offset > b_offset) - (a_offset < b_offset);
-}
-
-static int repo_dirent_is_dir(struct repo_dirent *dent)
-{
- return dent != NULL && dent->mode == REPO_MODE_DIR;
-}
-
-static struct repo_dir *repo_dir_from_dirent(struct repo_dirent *dent)
-{
- if (!repo_dirent_is_dir(dent))
- return NULL;
- return dir_pointer(dent->content_offset);
-}
-
-static struct repo_dir *repo_clone_dir(struct repo_dir *orig_dir)
-{
- uint32_t orig_o, new_o;
- orig_o = dir_offset(orig_dir);
- if (orig_o >= dir_pool.committed)
- return orig_dir;
- new_o = dir_alloc(1);
- orig_dir = dir_pointer(orig_o);
- *dir_pointer(new_o) = *orig_dir;
- return dir_pointer(new_o);
-}
-
-static struct repo_dirent *repo_read_dirent(uint32_t revision, uint32_t *path)
+static struct strbuf dataref_buf = STRBUF_INIT;
+const char *repo_read_path(uint32_t *path)
{
- uint32_t name = 0;
- struct repo_dirent *key = dent_pointer(dent_alloc(1));
- struct repo_dir *dir = NULL;
- struct repo_dirent *dent = NULL;
- dir = repo_commit_root_dir(commit_pointer(revision));
- while (~(name = *path++)) {
- key->name_offset = name;
- dent = dent_search(&dir->entries, key);
- if (dent == NULL || !repo_dirent_is_dir(dent))
- break;
- dir = repo_dir_from_dirent(dent);
- }
- dent_free(1);
- return dent;
-}
+ uint32_t unused;
-static void repo_write_dirent(uint32_t *path, uint32_t mode,
- uint32_t content_offset, uint32_t del)
-{
- uint32_t name, revision, dir_o = ~0, parent_dir_o = ~0;
- struct repo_dir *dir;
- struct repo_dirent *key;
- struct repo_dirent *dent = NULL;
- revision = active_commit;
- dir = repo_commit_root_dir(commit_pointer(revision));
- dir = repo_clone_dir(dir);
- commit_pointer(revision)->root_dir_offset = dir_offset(dir);
- while (~(name = *path++)) {
- parent_dir_o = dir_offset(dir);
-
- key = dent_pointer(dent_alloc(1));
- key->name_offset = name;
-
- dent = dent_search(&dir->entries, key);
- if (dent == NULL)
- dent = key;
- else
- dent_free(1);
-
- if (dent == key) {
- dent->mode = REPO_MODE_DIR;
- dent->content_offset = 0;
- dent_insert(&dir->entries, dent);
- }
-
- if (dent_offset(dent) < dent_pool.committed) {
- dir_o = repo_dirent_is_dir(dent) ?
- dent->content_offset : ~0;
- dent_remove(&dir->entries, dent);
- dent = dent_pointer(dent_alloc(1));
- dent->name_offset = name;
- dent->mode = REPO_MODE_DIR;
- dent->content_offset = dir_o;
- dent_insert(&dir->entries, dent);
- }
-
- dir = repo_dir_from_dirent(dent);
- dir = repo_clone_dir(dir);
- dent->content_offset = dir_offset(dir);
- }
- if (dent == NULL)
- return;
- dent->mode = mode;
- dent->content_offset = content_offset;
- if (del && ~parent_dir_o)
- dent_remove(&dir_pointer(parent_dir_o)->entries, dent);
-}
-
-uint32_t repo_read_path(uint32_t *path)
-{
- uint32_t content_offset = 0;
- struct repo_dirent *dent = repo_read_dirent(active_commit, path);
- if (dent != NULL)
- content_offset = dent->content_offset;
- return content_offset;
+ strbuf_reset(&dataref_buf);
+ fast_export_ls(path, &unused, &dataref_buf);
+ return dataref_buf.buf;
}
uint32_t repo_read_mode(const uint32_t *path)
{
- struct repo_dirent *dent = repo_read_dirent(active_commit, path);
- if (dent == NULL)
- die("invalid dump: path to be modified is missing");
- return dent->mode;
+ uint32_t result;
+ struct strbuf unused = STRBUF_INIT;
+
+ fast_export_ls(path, &result, &unused);
+ strbuf_release(&unused);
+ return result;
}
void repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst)
{
- uint32_t mode = 0, content_offset = 0;
- struct repo_dirent *src_dent;
- src_dent = repo_read_dirent(revision, src);
- if (src_dent != NULL) {
- mode = src_dent->mode;
- content_offset = src_dent->content_offset;
- repo_write_dirent(dst, mode, content_offset, 0);
- }
-}
+ uint32_t mode;
+ struct strbuf data = STRBUF_INIT;
-void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark)
-{
- repo_write_dirent(path, mode, blob_mark, 0);
+ fast_export_ls_rev(revision, src, &mode, &data);
+ fast_export_modify(REPO_MAX_PATH_DEPTH, dst, mode, data.buf);
+ strbuf_release(&data);
}
void repo_delete(uint32_t *path)
{
- repo_write_dirent(path, 0, 0, 1);
-}
-
-static void repo_git_add_r(uint32_t depth, uint32_t *path, struct repo_dir *dir);
-
-static void repo_git_add(uint32_t depth, uint32_t *path, struct repo_dirent *dent)
-{
- if (repo_dirent_is_dir(dent))
- repo_git_add_r(depth, path, repo_dir_from_dirent(dent));
- else
- fast_export_modify(depth, path,
- dent->mode, dent->content_offset);
-}
-
-static void repo_git_add_r(uint32_t depth, uint32_t *path, struct repo_dir *dir)
-{
- struct repo_dirent *de = repo_first_dirent(dir);
- while (de) {
- path[depth] = de->name_offset;
- repo_git_add(depth + 1, path, de);
- de = dent_next(&dir->entries, de);
- }
-}
-
-static void repo_diff_r(uint32_t depth, uint32_t *path, struct repo_dir *dir1,
- struct repo_dir *dir2)
-{
- struct repo_dirent *de1, *de2;
- de1 = repo_first_dirent(dir1);
- de2 = repo_first_dirent(dir2);
-
- while (de1 && de2) {
- if (de1->name_offset < de2->name_offset) {
- path[depth] = de1->name_offset;
- fast_export_delete(depth + 1, path);
- de1 = dent_next(&dir1->entries, de1);
- continue;
- }
- if (de1->name_offset > de2->name_offset) {
- path[depth] = de2->name_offset;
- repo_git_add(depth + 1, path, de2);
- de2 = dent_next(&dir2->entries, de2);
- continue;
- }
- path[depth] = de1->name_offset;
-
- if (de1->mode == de2->mode &&
- de1->content_offset == de2->content_offset) {
- ; /* No change. */
- } else if (repo_dirent_is_dir(de1) && repo_dirent_is_dir(de2)) {
- repo_diff_r(depth + 1, path,
- repo_dir_from_dirent(de1),
- repo_dir_from_dirent(de2));
- } else if (!repo_dirent_is_dir(de1) && !repo_dirent_is_dir(de2)) {
- repo_git_add(depth + 1, path, de2);
- } else {
- fast_export_delete(depth + 1, path);
- repo_git_add(depth + 1, path, de2);
- }
- de1 = dent_next(&dir1->entries, de1);
- de2 = dent_next(&dir2->entries, de2);
- }
- while (de1) {
- path[depth] = de1->name_offset;
- fast_export_delete(depth + 1, path);
- de1 = dent_next(&dir1->entries, de1);
- }
- while (de2) {
- path[depth] = de2->name_offset;
- repo_git_add(depth + 1, path, de2);
- de2 = dent_next(&dir2->entries, de2);
- }
-}
-
-static uint32_t path_stack[REPO_MAX_PATH_DEPTH];
-
-void repo_diff(uint32_t r1, uint32_t r2)
-{
- repo_diff_r(0,
- path_stack,
- repo_commit_root_dir(commit_pointer(r1)),
- repo_commit_root_dir(commit_pointer(r2)));
-}
-
-void repo_commit(uint32_t revision, uint32_t author, char *log, uint32_t uuid,
- uint32_t url, unsigned long timestamp)
-{
- fast_export_commit(revision, author, log, uuid, url, timestamp);
- dent_commit();
- dir_commit();
- active_commit = commit_alloc(1);
- commit_pointer(active_commit)->root_dir_offset =
- commit_pointer(active_commit - 1)->root_dir_offset;
-}
-
-static void mark_init(void)
-{
- uint32_t i;
- mark = 1024 * 1024 * 1024;
- for (i = 0; i < dent_pool.size; i++)
- if (!repo_dirent_is_dir(dent_pointer(i)) &&
- dent_pointer(i)->content_offset > mark)
- mark = dent_pointer(i)->content_offset;
- mark++;
+ fast_export_delete(REPO_MAX_PATH_DEPTH, path);
}
void repo_init(void)
{
- mark_init();
- if (commit_pool.size == 0) {
- /* Create empty tree for commit 0. */
- commit_alloc(1);
- commit_pointer(0)->root_dir_offset = dir_alloc(1);
- dir_pointer(0)->entries.trp_root = ~0;
- dir_commit();
- }
- /* Preallocate next commit, ready for changes. */
- active_commit = commit_alloc(1);
- commit_pointer(active_commit)->root_dir_offset =
- commit_pointer(active_commit - 1)->root_dir_offset;
}
void repo_reset(void)
{
- pool_reset();
- commit_reset();
- dir_reset();
- dent_reset();
}
diff --git a/vcs-svn/repo_tree.h b/vcs-svn/repo_tree.h
index 0499a19..559f99f 100644
--- a/vcs-svn/repo_tree.h
+++ b/vcs-svn/repo_tree.h
@@ -14,7 +14,7 @@
uint32_t next_blob_mark(void);
void repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst);
void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark);
-uint32_t repo_read_path(uint32_t *path);
+const char *repo_read_path(uint32_t *path);
uint32_t repo_read_mode(const uint32_t *path);
void repo_delete(uint32_t *path);
void repo_commit(uint32_t revision, uint32_t author, char *log, uint32_t uuid,
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index 31c6056..68a8435 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c
@@ -20,9 +20,11 @@
#define NODEACT_CHANGE 1
#define NODEACT_UNKNOWN 0
-#define DUMP_CTX 0
-#define REV_CTX 1
-#define NODE_CTX 2
+/* States: */
+#define DUMP_CTX 0 /* dump metadata */
+#define REV_CTX 1 /* revision metadata */
+#define NODE_CTX 2 /* node metadata */
+#define INTERNODE_CTX 3 /* between nodes */
#define LENGTH_UNKNOWN (~0)
#define DATE_RFC2822_LEN 31
@@ -198,13 +200,12 @@ static void read_props(void)
static void handle_node(void)
{
- uint32_t mark = 0, old_mode, old_mark;
+ uint32_t old_mode;
+ const char *old_data;
const uint32_t type = node_ctx.type;
const int have_props = node_ctx.propLength != LENGTH_UNKNOWN;
const int have_text = node_ctx.textLength != LENGTH_UNKNOWN;
- if (have_text)
- mark = next_blob_mark();
if (node_ctx.action == NODEACT_DELETE) {
if (have_text || have_props || node_ctx.srcRev)
die("invalid dump: deletion node has "
@@ -224,18 +225,15 @@ static void handle_node(void)
die("invalid dump: directories cannot have text attached");
/*
- * Find old content (old_mark) and decide on the new content (mark)
- * and mode (node_ctx.type).
+ * Find old content (old_data) and decide on the new mode.
*/
if (node_ctx.action == NODEACT_CHANGE && !~*node_ctx.dst) {
if (type != REPO_MODE_DIR)
die("invalid dump: root of tree is not a regular file");
- old_mark = 0;
+ old_data = NULL;
} else if (node_ctx.action == NODEACT_CHANGE) {
uint32_t mode;
- old_mark = repo_read_path(node_ctx.dst);
- if (!have_text)
- mark = old_mark;
+ old_data = repo_read_path(node_ctx.dst);
mode = repo_read_mode(node_ctx.dst);
if (mode == REPO_MODE_DIR && type != REPO_MODE_DIR)
die("invalid dump: cannot modify a directory into a file");
@@ -243,9 +241,12 @@ static void handle_node(void)
die("invalid dump: cannot modify a file into a directory");
node_ctx.type = mode;
} else if (node_ctx.action == NODEACT_ADD) {
- if (!have_text && type != REPO_MODE_DIR)
+ if (type == REPO_MODE_DIR)
+ old_data = NULL;
+ else if (have_text)
+ old_data = EMPTY_BLOB_SHA1_HEX;
+ else
die("invalid dump: adds node without text");
- old_mark = 0;
} else {
die("invalid dump: Node-path block lacks Node-action");
}
@@ -264,28 +265,35 @@ static void handle_node(void)
/*
* Save the result.
*/
- repo_add(node_ctx.dst, node_ctx.type, mark);
- if (!have_text)
+ if (type == REPO_MODE_DIR) /* directories are not tracked. */
return;
+ if (!have_text) {
+ fast_export_modify(REPO_MAX_PATH_DEPTH, node_ctx.dst, node_ctx.type,
+ old_data);
+ return;
+ }
if (!node_ctx.text_delta) {
- fast_export_blob(node_ctx.type, mark, node_ctx.textLength, &input);
+ fast_export_modify(REPO_MAX_PATH_DEPTH, node_ctx.dst, node_ctx.type,
+ "inline");
+ fast_export_data(node_ctx.type, node_ctx.textLength, &input);
return;
}
- if (node_ctx.srcRev) {
- fast_export_blob_delta_rev(node_ctx.type, mark, old_mode,
- node_ctx.srcRev, node_ctx.src,
+ fast_export_delta(node_ctx.dst, node_ctx.type, old_mode, old_data,
node_ctx.textLength, &input);
+}
+
+static void begin_revision(void)
+{
+ if (!rev_ctx.revision) /* revision 0 gets no git commit. */
return;
- }
- fast_export_blob_delta(node_ctx.type, mark, old_mode, old_mark,
- node_ctx.textLength, &input);
+ fast_export_begin_commit(rev_ctx.revision, rev_ctx.author, rev_ctx.log,
+ dump_ctx.uuid, dump_ctx.url, rev_ctx.timestamp);
}
-static void handle_revision(void)
+static void end_revision(void)
{
if (rev_ctx.revision)
- repo_commit(rev_ctx.revision, rev_ctx.author, rev_ctx.log,
- dump_ctx.uuid, dump_ctx.url, rev_ctx.timestamp);
+ fast_export_end_commit(rev_ctx.revision);
}
void svndump_read(const char *url)
@@ -315,13 +323,17 @@ void svndump_read(const char *url)
} else if (key == keys.revision_number) {
if (active_ctx == NODE_CTX)
handle_node();
+ if (active_ctx == REV_CTX)
+ begin_revision();
if (active_ctx != DUMP_CTX)
- handle_revision();
+ end_revision();
active_ctx = REV_CTX;
reset_rev_ctx(atoi(val));
} else if (key == keys.node_path) {
if (active_ctx == NODE_CTX)
handle_node();
+ if (active_ctx == REV_CTX)
+ begin_revision();
active_ctx = NODE_CTX;
reset_node_ctx(val);
} else if (key == keys.node_kind) {
@@ -363,7 +375,7 @@ void svndump_read(const char *url)
read_props();
} else if (active_ctx == NODE_CTX) {
handle_node();
- active_ctx = REV_CTX;
+ active_ctx = INTERNODE_CTX;
} else {
fprintf(stderr, "Unexpected content length header: %"PRIu32"\n", len);
buffer_skip_bytes(&input, len);
@@ -372,8 +384,10 @@ void svndump_read(const char *url)
}
if (active_ctx == NODE_CTX)
handle_node();
+ if (active_ctx == REV_CTX)
+ begin_revision();
if (active_ctx != DUMP_CTX)
- handle_revision();
+ end_revision();
}
int svndump_init(const char *filename)
@@ -385,6 +399,7 @@ int svndump_init(const char *filename)
reset_rev_ctx(0);
reset_node_ctx(NULL);
init_keys();
+ fast_export_empty_blob();
return 0;
}
--
1.7.2.4
^ permalink raw reply related
* [PATCH] transport-helper: avoid dependency on thread-utils.h
From: Jonathan Nieder @ 2010-12-10 11:48 UTC (permalink / raw)
To: git; +Cc: Ilari Liusvaara
Since the transport-helper does not use recursive mutexes or ask the
number of cores, it does not require any declarations from the
thread-utils lib. Removing the unnecessary #include avoids false
positives from "make CHECK_HEADER_DEPENDENCIES=1".
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
The #include directive in question was added in 7851b1e60
(remote-fd/ext: finishing touches after code review, 2010-11-17),
at the same times as the necessary #include for <pthread.h>.
This patch seems to work for me, but I wouldn't be surprised if
to be missing something.
transport-helper.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/transport-helper.c b/transport-helper.c
index 3a50856..7c99051 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -11,7 +11,6 @@
#ifndef NO_PTHREADS
#include <pthread.h>
-#include "thread-utils.h"
#endif
static int debug;
--
1.7.2.4
^ permalink raw reply related
* Re: [PATCH 10/18] gitweb: Adding isBinaryAction() and isFeedAction() to determine the action type
From: Jakub Narebski @ 2010-12-10 12:10 UTC (permalink / raw)
To: J.H.; +Cc: git
In-Reply-To: <4D01A103.3090900@eaglescrag.net>
On Fri, 10 Dec 2010, J.H. wrote:
>>> This is fairly self explanatory, these are here just to centralize the checking
>>> for these types of actions, as special things need to be done with regards to
>>> them inside the caching engine.
>>>
>>> isBinaryAction() returns true if the action deals with creating binary files
>>> (this needing :raw output)
>>
>> Why do you need special case binary / :raw output? It is not really
>> necessary if it is done in right way, as shown in my rewrite.
>
> Because that's not how my caching engine does it, and the reason for
> that is I am mimicking how the rest of gitweb does it.
To shorten the explanation why treating binary (needing :raw) output in
a special way is not necessary: with the way gitweb code is structured
(with "binmode STDOUT, ':raw'" inside action subroutine), with the way
capturing output is done (by redirecting STDOUT), and even with the way
kernel.org caching code is structured the only thing that needs to be
done to support both text (:utf8, as set at beginning of gitweb) and
binary (:raw) output is to *dump cache to STDOUT in binary mode*:
binmode $cache_fh, ':raw';
binmode STDOUT, ':raw';
File::Copy::copy($fh, \*STDOUT);
Nothing more.
Just dump cache file to STDOUT in binary mode.
> I attempted at one point to do as you were suggesting, and it became too
> cumbersome. I eventually broke out the 'binary' packages into a special
> case (thus mimicking how gitweb is already doing things), which also
> gives me the advantage of being able to checksum the resulting binary
> out of band, as well as being able to more trivially calculate the file
> size being sent.
I don't see how it needs to be special-cased: the ordinary output would
also take advantage of this. Note that plain 'blob' action can also
be quite large.
If there is to be done smarter, i.e. HTTP-aware, parsing and dumping of
cache entry file, e.g. by reading the HTTP header part to memory and
fiddling with HTTP headers (e.g. adding Content-Length header), it can be
done in a contents-agnostic way.
Note that with the way I do it in my rewrite, namely saving cached output
to temporary file to rename it to final destination later (atomic update),
we can do mungling of HTTP headers before/during this final copying to
final file, e.g. calculating Content-Length and perhaps Content-MD5
headers.
>
>>> isFeedAction() returns true if the action deals with a news feed of some sort,
>>> basically used to bypass the 'Generating...' message should it be a news reader
>>> as those will explode badly on that page.
>>
>> Why blacklisting 'feed', instead of whitelisting HTML-output?
>
> There are a limited number of feed types and their ilk (standard xml
> formatted feed and atom), there are lots of html-output like things.
> Easier to default and have things work, generally, than to have things
> not work the way you would expect.
Ah, I see from what you written in other subthreads of this thread that
you prefer to have "Generating..." page where it is not wanted that not
have it where it could be useful (i.e. blacklist approach), while I took
the opposite side (i.e. whitelist approach).
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [PATCH 10/18] gitweb: Adding isBinaryAction() and isFeedAction() to determine the action type
From: Jakub Narebski @ 2010-12-10 12:25 UTC (permalink / raw)
To: J.H.; +Cc: git
In-Reply-To: <201012101310.55094.jnareb@gmail.com>
On Fri, 10 Dec 2010, Jakub Narebski wrote:
> On Fri, 10 Dec 2010, J.H. wrote:
>
>>>> This is fairly self explanatory, these are here just to centralize the checking
>>>> for these types of actions, as special things need to be done with regards to
>>>> them inside the caching engine.
>>>>
>>>> isBinaryAction() returns true if the action deals with creating binary files
>>>> (this needing :raw output)
>>>
>>> Why do you need special case binary / :raw output? It is not really
>>> necessary if it is done in right way, as shown in my rewrite.
>>
>> Because that's not how my caching engine does it, and the reason for
>> that is I am mimicking how the rest of gitweb does it.
>
> To shorten the explanation why treating binary (needing :raw) output in
> a special way is not necessary: with the way gitweb code is structured
> (with "binmode STDOUT, ':raw'" inside action subroutine), with the way
> capturing output is done (by redirecting STDOUT), and even with the way
> kernel.org caching code is structured the only thing that needs to be
> done to support both text (:utf8, as set at beginning of gitweb) and
> binary (:raw) output is to *dump cache to STDOUT in binary mode*:
>
> binmode $cache_fh, ':raw';
> binmode STDOUT, ':raw';
> File::Copy::copy($fh, \*STDOUT);
>
> Nothing more.
>
> Just dump cache file to STDOUT in binary mode.
Note that special-casing binary output means that you would never be able
to replace custom caching engine with e.g. CHI with Memcached backend,
because that treating some actions in a special way interleaves gitweb
code with guts of caching code.
And memcached might be a way that kernel.org would have to go...
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: git-cvsimport with cvsps output in commit msg breaks imports
From: Michael J Gruber @ 2010-12-10 12:48 UTC (permalink / raw)
To: Thomas Adam; +Cc: git, cvsps
In-Reply-To: <20101209220347.GA3180@shuttle.home>
Thomas Adam venit, vidit, dixit 09.12.2010 23:03:
> Hi all,
>
> [ I've Cced both the cvsps maintainer and the author listed for
> git-cvsimport in case it's more relevant to either tool. ]
>
> I am wondering if anyone here is able to shed some light on a problem I've
> encountered with git-cvsimport. For ages now, I've had an automatic
> conversion of a CVS repository to a Git one, using git-cvsimport to update a
> repository as commits happen in CVS.
>
> The repository in question is here:
>
> https://github.com/ThomasAdam/tmux
>
> Everything is on the Master branch.
>
> More specifically, the commit which I think introduced the problem, and all
> subsequent commits thereafter is here:
>
> https://github.com/ThomasAdam/tmux/commit/f0220a10b01a764e0dc52ea1b2407f58600a30eb
>
> Note that from this commit onwards, the commit *message* has a bunch of
> cvsps output in it. I can only surmise that this somehow causes problems
> for cvsimport.
>
> But I can't say for sure.
The previous one has cvsps info in the commit message already, prefixed
with "|". So the problem is the previous one or the one before.
If you have cvs checkout, can spot anything between those? Can you redo
the cvsps import from that point on and check cvsps log?
Michael
^ permalink raw reply
* git notes and git-commit
From: Nguyen Thai Ngoc Duy @ 2010-12-10 13:11 UTC (permalink / raw)
To: Git Mailing List
Hi,
I have never used git-notes before, just have had a quick look over
git-notes.txt so this may have already been discussed.
Isn't it more convenient to write/update notes when editing commit
message? Jakub mentioned of "---" in the archive elsewhere. There's
notes.rewriteRef for commit --amend. But if I amend a commit, I might
as well change my notes. rewriteRef would not work with "git commit
-c" either.
Another (probably silly) thing. Can I temporarily attach notes to
HEAD? I could add up notes while working, the notes show up when I
edit for commit message. I could make revise the notes a bit and
commit. Then the notes are attached to a commit.
--
Duy
^ permalink raw reply
* Re: [PATCH 0/2] [RFD] Using gitrevisions :/search style with other operators
From: Nguyen Thai Ngoc Duy @ 2010-12-10 13:25 UTC (permalink / raw)
To: Junio C Hamano
Cc: Jonathan Nieder, Jakub Narebski, git, Kevin Ballard, Yann Dirson,
Jeff King
In-Reply-To: <7vsjy7h3db.fsf@alter.siamese.dyndns.org>
On Thu, Dec 9, 2010 at 1:22 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>
>> Jakub Narebski wrote:
>>
>>> You would need HEAD{^{/foo}^@}x3, or use special rule that HEAD^{/foo}x2
>>> means really HEAD^{/foo}^@^{/foo}, with ^@ used to join them.
>>
>> That said, does ^2x500 really do something meaningful that a person
>> would ever need? I like the
>>
>> ^{:nth(3)/foo}
>>
>> syntax because perl6 supports m:nth(3)/foo/, suggesting a menu of
>> already-defined modifiers to implement when they prove useful,...
>
> Can you explain what the colon in "$commit^{:nth(3)/foo}" is doing?
>
> Are we declaring anything that begins with ':' is a magic inside ^{...}
> construct?
>
> I do not think nth($n) without specifying where to start (iow, what the
> current ":/foo" implementation does but with "three levels deep") makes
> any sense, but because the main point of your argument is that we can have
> modifies other than nth($n) that may make sense in such a context, I would
> want to make sure anything we come up with is extensible to that syntax.
There's also another similar operation: note search. I don't think we
need to invent another syntax for note search, a modifier for ^{/foo}
may be a good choice.
> On the "starting from any ref" front, I think "!" (as in ":/!some magic")
> was the introducer we reserved for such a magic some time ago, so perhaps
> on the "starting from this commit" side, "^{!magic/foo}" may be more
> appropriate?
Can we use ! modifier for other ^{} too? What I have in mind is how to
say ^{commit} that has two parents. Or even better, "search from the
given tip for a commit that has two parents and the commit message
matches 'foo'". Hmm.. too complex. Perhaps "^{grep: <grep arguments>}"
that pulls the whole git-grep functionality in.
--
Duy
^ permalink raw reply
* Re: [PATCH 14/14] wt-status.c: Initialise variable to suppress msvc warning
From: Sebastian Schuberth @ 2010-12-10 13:35 UTC (permalink / raw)
To: kusmabite
Cc: Junio C Hamano, Ramsay Jones, Jonathan Nieder, Johannes Sixt,
GIT Mailing-list
In-Reply-To: <AANLkTi=SzDhoQnLeKUvWe7A6r-7MT-DTLuDGLprqid9X@mail.gmail.com>
On Thu, Dec 9, 2010 at 20:46, Erik Faye-Lund <kusmabite@gmail.com> wrote:
> On Thu, Dec 9, 2010 at 8:08 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> Ramsay Jones <ramsay@ramsay1.demon.co.uk> writes:
>>
>>> Junio, could you please drop patches 5-14 from the series; the first four patches
>>> are the important ones and I'd rather they didn't get held up. Thanks!
>>
>> Have these four patches been Acked by interested parties?
>>
>> I think I saw 1/N and 2/N acked by Erik and 4/N acked by SSchuberth and
>> J6t, but any words on 3/N?
>>
>> Not that I deeply care nor have environment to test changes to [3/N], but
>> I am wondering if these need conditional definition to futureproof (e.g.
>> what happens when the header you are using the definition _I64_MIN from,
>> or some other headers, started defining these constats?).
>
> I'm not sure if I follow this entirely. _I64_MIN is defined by
> limits.h on Windows, and limits.h has a header-guard (or "#pragma
> once" as Microsoft-code tends to prefer).
>
> Oh, right. You mean if someone else starts defining INTMAX_MAX etc? If
> someone includes an stdint/inttypes-implementation while including
> git-compat-util.h, we're going to have a boat-load of similar issues
> anyway. I think guarding them is something that's better left to when
> we encounter the problem (if ever).
FYI: In contrast to previous versions, Visual Studio 2010 ships with a
stdint.h header which defines INTMAX_MAX etc. However, that stdint.h
is not included by limits.h (in fact, not by *any* other shipping
header file, as it seems), so we should not run into any trouble even
with VS2010.
So I agree with Erik about patch 3/N:
Acked-by: Sebastian Schuberth <sschuberth@gmail.com>
--
Sebastian Schuberth
^ permalink raw reply
* Re: [PATCH 07/18] gitweb: Revert back to $cache_enable vs. $caching_enabled
From: Jakub Narebski @ 2010-12-10 13:48 UTC (permalink / raw)
To: J.H.; +Cc: git
In-Reply-To: <4D019288.9060503@eaglescrag.net>
On Fri, 10 Dec 2010, J.H. wrote:
> > Formally, there is no backward compatibility with any released code.
> > Using out-of-tree patches is on one's own risk.
>
> I will have to beg to differ with you on this, the entirety of the
> existing caching engine has been released code for a number of years,
> there are rpm packages available for it, at the very least, in Fedora
> and in EPEL.
>
> The caching engine *IS* released code, and this patchset is as much a
> new feature as an attempt to merge a fork. Kernel.org isn't the only
> one running this code, and that has been the case for several years now
> already.
>
> Claiming that this isn't released code is doing me a disservice to me,
> and those who have submitted patches to it independent of git and the
> mainline gitweb.
>
> Thinking about the patch series outside of that context will lead to me
> putting my foot down and arguing on those other users behalf. I'm not
> keen on breaking them for no good reason, and I'm not seeing your change
> here as one that's particularly worthwhile, while causing external
> breakage for no reason.
I am so very sorry. Please excuse me. I didn't intent this to be arguing
against backwards compatibility with what amounts to gitweb fork, but rather
grumbling about maintaining our mistakes due to backwards compatibility
requirement. I see now that it reads as arguing for breaking backwards
compatibility: the "Formally" qualifier is too weak.
That said I would rather there was no need for forking, or at least for
the caching patches to be peer-reviewed on git mailing list, even if they
wouldn't be accepted / merged in, or merged in soon enough to avoid need
for fork.
>
> > But even discarding that, I'd rather use the same solution as in
> >
> > [PATCHv6/RFC 22/24] gitweb: Support legacy options used by kernel.org caching engine
> > http://thread.gmane.org/gmane.comp.version-control.git/163052/focus=163058
> > http://repo.or.cz/w/git/jnareb-git.git/commitdiff/27ec67ad90ecd56ac3d05f6a9ea49b6faabf7d0a
> >
> > i.e.
> >
> > our $cache_enable;
> >
> > [...]
> >
> > # somewhere just before call to cache_fetch()
> > $caching_enabled = !!$cache_enable if defined $cache_enable;
> >
> >>
> >> This reverts back to the previous variable to enable / disable caching
>
> Is there really any point in changing the name at all? The intention of
> cache_enable, at one point, was to allow for other caching engines and
> while there aren't any other caching engines that use it, it's already
> treated identically to cache_enable.
>
> If it really adds enough to the readability to the code, then I'm fine
> with adding:
>
> $caching_enabled = $cache_enable if defined $cache_enable;
>
> But now you are setting up two variables that control the same thing,
> adding the possibility for conflicts and confusion to end users.
>
> I just want that stated.
I guess I can live (I'd have to live) with $cache_enable instead of
$caching_enabled as name of *boolean* variable controlling whether
caching is turned on or off. Though I'd argue that $caching_enabled
is better name:
if ($caching_enabled) {
reads naturally as "if caching [is] enabled"; not so with $cache_enable.
$cache_enable as enum is just a bad, bad idea, as is conflating enabling
caching with selecting caching engine (c.f. http://lwn.net/Articles/412131/
though only very peripherally - it is about other "conflated designs").
BTW. when leaving $cache_enable from "[PATCHv6/RFC 22/24] gitweb: Support
legacy options used by kernel.org caching engine" I forgot that it is
actually $cache_enable (which is 0 by default) that needs to be set up
if one wants caching. All the rest of cache config variables can be left
at their default values... though, J.H., are they?
>
> Also, why the double negative in your original snippet - that doesn't
> entirely make sense....
I don't know why I felt that I needed to convert it to bool...
--
Jakub Narebski
Poland
^ permalink raw reply
* [PATCH] Preserve Entry class key bindings for SHA id
From: Kacper Kornet @ 2010-12-10 13:34 UTC (permalink / raw)
To: git; +Cc: paulus
If bind is specified for key without any modifier, then any combination
of modifiers may be present in the event. So bind $e $ev "$escript;
break" breaks some useful bindings from Entry class (for example
Ctrl+k).
---
gitk | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/gitk b/gitk
index 45e3380..0c6f3af 100755
--- a/gitk
+++ b/gitk
@@ -2365,6 +2365,10 @@ proc makewindow {} {
}
}
+ foreach e $entries {
+ bindtags $e [linsert [bindtags $e] 2 entrybind]
+ }
+
bind .pwbottom <Configure> {resizecdetpanes %W %w}
pack .ctop -fill both -expand 1
bindall <1> {selcanvline %W %x %y}
@@ -2563,12 +2567,8 @@ proc scrollcanv {cscroll f0 f1} {
proc bindkey {ev script} {
global entries
bind . $ev $script
- set escript [bind Entry $ev]
- if {$escript == {}} {
- set escript [bind Entry <Key>]
- }
foreach e $entries {
- bind $e $ev "$escript; break"
+ bind entrybind $ev "break"
}
}
--
1.7.3.3
--
Kacper Kornet
^ permalink raw reply related
* Re: [PATCH 15/18] gitweb: Add show_warning() to display an immediate warning, with refresh
From: Jakub Narebski @ 2010-12-10 14:10 UTC (permalink / raw)
To: J.H.; +Cc: git
In-Reply-To: <4D01D902.1030102@eaglescrag.net>
On Fri, 10 Dec 2010, J.H. wrote:
> On 12/09/2010 05:01 PM, Jakub Narebski wrote:
>> "John 'Warthog9' Hawley" <warthog9@eaglescrag.net> writes:
>>
>>> die_error() is an immediate and abrupt action. show_warning() more or less
>>> functions identically, except that the page generated doesn't use the
>>> gitweb header or footer (in case they are broken) and has an auto-refresh
>>> (10 seconds) built into it.
>>
>> Why not use gitweb header/footer? If they are broken, it should be
>> caught in git development. If we don't se them, the show_warning()
>> output would look out of place.
>
> The only other 'transient' style page, the 'Generating...' page doesn't
> use it, and I felt that since this was also transient, and only (likely)
> to be seen once it wasn't worth the header & footer.
>
> That said I've added it back in, in v9.
Well, the contents and feel of show_warning() is more like die_error()
rather than "Generating..." page, so I feel that if die_error() conforms
to style of rest of gitweb pages, then show_warning() should too.
>>> +sub show_warning {
>>> + $| = 1;
>>
>> + local $| = 1;
>>
>> $| is global variable, and otherwise you would turn autoflush for all
>> code, which would matter e.g. for FastCGI.
>
> Since the execution exits immediately after, wouldn't FastCGI reset at
> that point, since execution of that thread has stopped? Or does FastCGI
> retain everything as is across subsequent executions of a process?
Well, with exit(0) it is a moot point... but it is good habit to localize
punctation variables ($|, $/,)
>>> +<meta http-equiv="refresh" content="10"/>
>>
>> Why 10 seconds?
>
> Long enough to see the error, but not too long to be a nuisance. Mainly
> just there to warn the admin that it did something automatic they may
> not have been expecting.
A comment if you please, then?
Hmmm... I guess there is no ned to make it configurable.
>>> +</head>
>>> +<body>
>>> +$warning
>>> +</body>
>>> +</html>
>>> +EOF
>>> + exit(0);
>>
>> "exit(0)" and not "goto DONE_GITWEB", or "goto DONE_REQUEST"?
>
> DONE_REQUEST doesn't actually exist as a label,
Errr... DONE_REQUEST was introduced in
[PATCH/RFC] gitweb: Go to DONE_REQUEST rather than DONE_GITWEB in die_error
Message-ID: <1290723308-21685-1-git-send-email-jnareb@gmail.com>
http://permalink.gmane.org/gmane.comp.version-control.git/162156
> the exit was used
> partially for my lack of love for goto's, but mostly out of not
> realizing what that was calling back to (mainly for the excitement of
> things like PSGI and their ilk)
You would have to do more than that. ModPerl::Registry that is used
for mod_perl support (which as deployment is I guess more widespread
than PSGI via wrapper using Plack::App::WrapCGI, or FastCGI deployment)
redefines 'exit' so that CGI scripts that use 'exit' to end request
keep working without need to restart worker at each request; for real
exit, for example from background process, you need to use CORE::exit.
See e.g. http://repo.or.cz/w/git/jnareb-git.git/commitdiff/8bd99a6d37cc
the ->_set_maybe_background() method.
>
> I will change that that, but considering there are other locations where
> I do explicit exit's and those are actually inherent to the way the
> caching engine currently works, I might need to go take a look at what's
> going on with respect to multi-threaded items inside of PSGI and their
> like. It's possible the caching engine doesn't actually work on those...
That would be a pity. In my rewrite I tried to take into acount both
non-persistent (plain CGI, running as script) and persistent (mod_perl,
FastCGI, PSGI) web environments.
>>> +}
>>> +
>>> sub isBinaryAction {
>>> my ($action) = @_;
>>
>> Didn't you ran gitweb tests?
>
> I did, they passed for me - for whatever reason my cache dir wasn't
> cleaned up, and stayed resident once it was created.
Hmmm... I wonder why new tests in t9502 and t9503 didn't pass for me...
P.S. I'll write separate email about problems with die_error, die-ing
and output caching.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: git notes and git-commit
From: Johan Herland @ 2010-12-10 14:13 UTC (permalink / raw)
To: git; +Cc: Nguyen Thai Ngoc Duy
In-Reply-To: <AANLkTi=q1F7WEgH+dLKTHOKhsNVuhU=OeyJ2AsP7oW2G@mail.gmail.com>
On Friday 10 December 2010, Nguyen Thai Ngoc Duy wrote:
> Hi,
>
> I have never used git-notes before, just have had a quick look over
> git-notes.txt so this may have already been discussed.
>
> Isn't it more convenient to write/update notes when editing commit
> message? Jakub mentioned of "---" in the archive elsewhere. There's
> notes.rewriteRef for commit --amend. But if I amend a commit, I might
> as well change my notes. rewriteRef would not work with "git commit
> -c" either.
It seems your notes data is very much tied to your commit messages. If
your notes needs editing every time you edit the commit message, I have
to ask why you simply don't fold the notes into the commit message.
The same goes for rewriteRef vs. "git commit -c". If the notes should
follow the commit message around, I have to ask why the notes are
separate from the commit message in the first place.
That said, there might well be good use cases for this (e.g. using notes
to store data types - e.g. binary data - that cannot be part of the
commit message), so I will not advise against implementing this, but if
you do, please also consider that there are notes use cases where the
notes are tied to the actual contents of the commit, and not the commit
message (e.g. notes-cache).
> Another (probably silly) thing. Can I temporarily attach notes to
> HEAD? I could add up notes while working, the notes show up when I
> edit for commit message. I could make revise the notes a bit and
> commit. Then the notes are attached to a commit.
Currently, this does not exist. However, a co-worker of mine suggested a
feature recently that would benefit from what you describe above:
<digression>
When cherry-picking, instead of using -x to store "(cherry picked from
commit 1234567...)" in the commit message, it would be nice to use
(e.g.) -X to store that message in a note. Storing these annotations in
notes instead of in the commit message allows us to clean them up (i.e.
removing references to now-unreachable commits) at a later date,
without rewriting history.
However, in order for this to work together
with "cherry-pick --no-commit", we need somewhere to store the note
until the subsequent 'git commit' (i.e. something similar
to .git/MERGE_MSG, but for notes).
</digression>
Implementing something for notes analogous to .git/MERGE_MSG for commit
messages would indeed be interesting. AFAICS, that also solves your
request for editing notes for commits-in-progress.
...Johan
--
Johan Herland, <johan@herland.net>
www.herland.net
^ permalink raw reply
* Re: git notes and git-commit
From: Nguyen Thai Ngoc Duy @ 2010-12-10 14:38 UTC (permalink / raw)
To: Johan Herland; +Cc: git
In-Reply-To: <201012101513.43890.johan@herland.net>
On Fri, Dec 10, 2010 at 9:13 PM, Johan Herland <johan@herland.net> wrote:
> On Friday 10 December 2010, Nguyen Thai Ngoc Duy wrote:
>> Hi,
>>
>> I have never used git-notes before, just have had a quick look over
>> git-notes.txt so this may have already been discussed.
>>
>> Isn't it more convenient to write/update notes when editing commit
>> message? Jakub mentioned of "---" in the archive elsewhere. There's
>> notes.rewriteRef for commit --amend. But if I amend a commit, I might
>> as well change my notes. rewriteRef would not work with "git commit
>> -c" either.
>
> It seems your notes data is very much tied to your commit messages. If
> your notes needs editing every time you edit the commit message, I have
> to ask why you simply don't fold the notes into the commit message.
Both commit message and notes are "notes" related to a commit. Some
info, like todos, I'd rather leave them out of commit message. I
wasn't clear what I was getting to. But as you said below, notes can
be cleaned up without rewriting history, making it separate from
commit message. So basically they all are just notes (with different
purpose), which makes me think they should be able to be edited at the
same time.
> The same goes for rewriteRef vs. "git commit -c". If the notes should
> follow the commit message around, I have to ask why the notes are
> separate from the commit message in the first place.
Aside from "all editable at the same time" above, I think related
notes should show up when I write commit messages. Notes can give
helpful info for writing commit message, even if I don't update them.
> That said, there might well be good use cases for this (e.g. using notes
> to store data types - e.g. binary data - that cannot be part of the
> commit message), so I will not advise against implementing this, but if
> you do, please also consider that there are notes use cases where the
> notes are tied to the actual contents of the commit, and not the commit
> message (e.g. notes-cache).
Ah, I didn't know this. Thanks.
--
Duy
^ permalink raw reply
* Re: [PATCH 14/14] wt-status.c: Initialise variable to suppress msvc warning
From: Erik Faye-Lund @ 2010-12-10 15:05 UTC (permalink / raw)
To: Sebastian Schuberth
Cc: Junio C Hamano, Ramsay Jones, Jonathan Nieder, Johannes Sixt,
GIT Mailing-list
In-Reply-To: <AANLkTinty08S2vT9ZSVQW03yL5uzrmqW7k_Ozad-q-E2@mail.gmail.com>
On Fri, Dec 10, 2010 at 2:35 PM, Sebastian Schuberth
<sschuberth@gmail.com> wrote:
> On Thu, Dec 9, 2010 at 20:46, Erik Faye-Lund <kusmabite@gmail.com> wrote:
>
>> On Thu, Dec 9, 2010 at 8:08 PM, Junio C Hamano <gitster@pobox.com> wrote:
>>> Ramsay Jones <ramsay@ramsay1.demon.co.uk> writes:
>>>
>>>> Junio, could you please drop patches 5-14 from the series; the first four patches
>>>> are the important ones and I'd rather they didn't get held up. Thanks!
>>>
>>> Have these four patches been Acked by interested parties?
>>>
>>> I think I saw 1/N and 2/N acked by Erik and 4/N acked by SSchuberth and
>>> J6t, but any words on 3/N?
>>>
>>> Not that I deeply care nor have environment to test changes to [3/N], but
>>> I am wondering if these need conditional definition to futureproof (e.g.
>>> what happens when the header you are using the definition _I64_MIN from,
>>> or some other headers, started defining these constats?).
>>
>> I'm not sure if I follow this entirely. _I64_MIN is defined by
>> limits.h on Windows, and limits.h has a header-guard (or "#pragma
>> once" as Microsoft-code tends to prefer).
>>
>> Oh, right. You mean if someone else starts defining INTMAX_MAX etc? If
>> someone includes an stdint/inttypes-implementation while including
>> git-compat-util.h, we're going to have a boat-load of similar issues
>> anyway. I think guarding them is something that's better left to when
>> we encounter the problem (if ever).
>
> FYI: In contrast to previous versions, Visual Studio 2010 ships with a
> stdint.h header which defines INTMAX_MAX etc. However, that stdint.h
> is not included by limits.h (in fact, not by *any* other shipping
> header file, as it seems), so we should not run into any trouble even
> with VS2010.
>
Very interesting, thanks. Did you try to compile Git on VS2010? This
sounds like a reason for me to install VS2010 on one of my machines...
:)
^ 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