* [PATCH v2 0/5] sha1_file: remove only current repository can have relative path limitation
@ 2011-09-06 10:24 Wang Hui
2011-09-06 10:24 ` [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check Wang Hui
0 siblings, 1 reply; 11+ messages in thread
From: Wang Hui @ 2011-09-06 10:24 UTC (permalink / raw)
To: gitster, git, tali
Hi Junio & Martin,
In the V1, Junio said we should investigate why the limitation is originally
designed. This limitation is introduced by Martin in the 2006, so add him
at this time, hope he can share some information and knowledge for this
question although he is not seen in the maillist recently.
Below is my investigation:
In the link_alt_odb_entry(), each alt object path will be added to the struct
alternate_object_database and linked to a list, but we don't permit a same dir
is added twice, otherwise it will easily introduce lots of trouble like
dead-loop reference. To compare if two directories are same, original design
is using memcmp() to directly compare directory path names, this method can't
give a accurate result if paths include .. and multiple slash, e.g. ../../a
and ../../b/../a is the same dir, but this method will report they are
different. Knowing the reason, i implement a new direcotry comparison function
to replace the old one, then we can safely remove multi-level relative
alternates limitation now.
0001 is a simple cleanup patch, has no relation with multi-level relative
limitation.
0002 is a bug fix, has no relation with multi-level relative limitation.
Without this fix, all tests under t/ can work well so far, this is because we
are lucky that the ent->base[pfxlen+1] is 0, if it is not 0, we will see lots
of fails. After apply this fix, it is safe now.
0003 introduce a new directory comparison function to replace the old one.
0004 remove the multi-level relative alternates limitation
0005 change and add testcase to validate multi-level relative alternates.
after apply those 5 patches, all testcase under t can pass.
Hui Wang (5):
sha1_file cleanup: remove redundant variable check
sha1_file: remove a buggy value setting
sha1_file: improve directories comparison method
sha1_file: remove relative entries limitation
t5710: add testcase for multi-level relative alternates
abspath.c | 26 ++++++++++++++++++++++++++
cache.h | 1 +
sha1_file.c | 22 +++++++---------------
t/t5710-info-alternate.sh | 21 +++++++++++++++++++--
4 files changed, 53 insertions(+), 17 deletions(-)
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check
2011-09-06 10:24 [PATCH v2 0/5] sha1_file: remove only current repository can have relative path limitation Wang Hui
@ 2011-09-06 10:24 ` Wang Hui
2011-09-06 10:24 ` [PATCH v2 2/5] sha1_file: remove a buggy value setting Wang Hui
2011-09-06 16:59 ` [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check Junio C Hamano
0 siblings, 2 replies; 11+ messages in thread
From: Wang Hui @ 2011-09-06 10:24 UTC (permalink / raw)
To: gitster, git, tali
From: Hui Wang <Hui.Wang@windriver.com>
This variable check is always true, so it is redundant and need to be
removed.
We can't remove the init value for this variable, since removing
it will introduce building warning:
'base_len' may be used uninitialized in this function.
Signed-off-by: Hui Wang <Hui.Wang@windriver.com>
---
sha1_file.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index f7c3408..d12a675 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -255,8 +255,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
if (!is_absolute_path(entry) && relative_base) {
/* Relative alt-odb */
- if (base_len < 0)
- base_len = strlen(relative_base) + 1;
+ base_len = strlen(relative_base) + 1;
entlen += base_len;
pfxlen += base_len;
}
--
1.6.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 2/5] sha1_file: remove a buggy value setting
2011-09-06 10:24 ` [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check Wang Hui
@ 2011-09-06 10:24 ` Wang Hui
2011-09-06 10:24 ` [PATCH v2 3/5] sha1_file: improve directories comparison method Wang Hui
2011-09-06 16:26 ` [PATCH v2 2/5] sha1_file: remove a buggy value setting Junio C Hamano
2011-09-06 16:59 ` [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check Junio C Hamano
1 sibling, 2 replies; 11+ messages in thread
From: Wang Hui @ 2011-09-06 10:24 UTC (permalink / raw)
To: gitster, git, tali
From: Hui Wang <Hui.Wang@windriver.com>
The ent->base[] is a character array, it has pfxlen characters from
position 0 to (pfxlen-1) to contain an alt object dir name, the
position pfxlen should be the string terminating character '\0' and
is deliberately set to '\0' at the previous code line. The position
(pfxlen+1) is given to ent->name.
>From above analysis, there is no reason to set ent->base[pfxlen] to
'/' at the end of this function, first it doesn't make sense to append
a '/' at the end of a dir name, second if you are not lucky that the
ent->base[pfxlen+1] is not 0, you will get a wrong alt object dir
name.
Signed-off-by: Hui Wang <Hui.Wang@windriver.com>
---
sha1_file.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index d12a675..5940d84 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -304,8 +304,6 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
/* recursively add alternates */
read_info_alternates(ent->base, depth + 1);
- ent->base[pfxlen] = '/';
-
return 0;
}
--
1.6.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 3/5] sha1_file: improve directories comparison method
2011-09-06 10:24 ` [PATCH v2 2/5] sha1_file: remove a buggy value setting Wang Hui
@ 2011-09-06 10:24 ` Wang Hui
2011-09-06 10:24 ` [PATCH v2 4/5] sha1_file: remove relative entries limitation Wang Hui
2011-09-06 16:32 ` [PATCH v2 3/5] sha1_file: improve directories comparison method Junio C Hamano
2011-09-06 16:26 ` [PATCH v2 2/5] sha1_file: remove a buggy value setting Junio C Hamano
1 sibling, 2 replies; 11+ messages in thread
From: Wang Hui @ 2011-09-06 10:24 UTC (permalink / raw)
To: gitster, git, tali
From: Hui Wang <Hui.Wang@windriver.com>
In the past, to check if two directory paths are same, we use memcmp()
to directly compare their path strings, this method can't get an
accurate result if paths include ".." or "." or redundant slash, e.g.
current dir is /, "/a/b/c", "/a/b//c/d/e/../.." and "./a/b/f/../c"
should be the same dir, but current method will identify they are
different.
Now add a global function is_same_directory() to replace the old
memcmp() method, this function will change two input paths to real
path first, then normalized them and compare them.
Signed-off-by: Hui Wang <Hui.Wang@windriver.com>
---
abspath.c | 26 ++++++++++++++++++++++++++
cache.h | 1 +
sha1_file.c | 4 ++--
3 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/abspath.c b/abspath.c
index 3005aed..7717f06 100644
--- a/abspath.c
+++ b/abspath.c
@@ -138,3 +138,29 @@ const char *absolute_path(const char *path)
}
return buf;
}
+
+/* Compare two directories, if they are the same dir, return 1, otherwise
+ * return 0.
+ *
+ * The input path can be relative or absolute one, before the comparison, they
+ * will be changed to real path first, then be normalized to remove .. and
+ * redundant slash, in the end, we will compare two real and normalized paths.
+ */
+int is_same_directory(const char *dir1, const char *dir2)
+{
+ const char *real_path1, *real_path2;
+ char norm_path1[PATH_MAX], norm_path2[PATH_MAX];
+
+ real_path1 = real_path(dir1);
+ if (normalize_path_copy(norm_path1, real_path1))
+ return 0;
+
+ real_path2 = real_path(dir2);
+ if (normalize_path_copy(norm_path2, real_path2))
+ return 0;
+
+ if (strlen(norm_path1) != strlen(norm_path2))
+ return 0;
+
+ return !memcmp(norm_path1, norm_path2, strlen(norm_path1));
+}
diff --git a/cache.h b/cache.h
index e11cf6a..70056b5 100644
--- a/cache.h
+++ b/cache.h
@@ -758,6 +758,7 @@ int longest_ancestor_length(const char *path, const char *prefix_list);
char *strip_path_suffix(const char *path, const char *suffix);
int daemon_avoid_alias(const char *path);
int offset_1st_component(const char *path);
+int is_same_directory(const char *dir1, const char *dir2);
/* object replacement */
#define READ_SHA1_FILE_REPLACE 1
diff --git a/sha1_file.c b/sha1_file.c
index 5940d84..18f7fb3 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -286,12 +286,12 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
* thing twice, or object directory itself.
*/
for (alt = alt_odb_list; alt; alt = alt->next) {
- if (!memcmp(ent->base, alt->base, pfxlen)) {
+ if (is_same_directory(ent->base, alt->base)) {
free(ent);
return -1;
}
}
- if (!memcmp(ent->base, objdir, pfxlen)) {
+ if (is_same_directory(ent->base, objdir)) {
free(ent);
return -1;
}
--
1.6.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 4/5] sha1_file: remove relative entries limitation
2011-09-06 10:24 ` [PATCH v2 3/5] sha1_file: improve directories comparison method Wang Hui
@ 2011-09-06 10:24 ` Wang Hui
2011-09-06 10:24 ` [PATCH v2 5/5] t5710: add testcase for multi-level relative alternates Wang Hui
2011-09-06 16:32 ` [PATCH v2 3/5] sha1_file: improve directories comparison method Junio C Hamano
1 sibling, 1 reply; 11+ messages in thread
From: Wang Hui @ 2011-09-06 10:24 UTC (permalink / raw)
To: gitster, git, tali
From: Hui Wang <Hui.Wang@windriver.com>
link_alt_odb_entries() will be called recursively if alternates has
valid object store paths, to avoid nesting too deep, the recursive
depth is limited to 5, this limitation is reasonable and safe for
dead-loop reference situation.
There is another limitation in this function to only permit the 1st
level alternates has relative paths, the purpose of this limitation
is to avoid inaccurate result when using memcmp() directly to compare
two directory path names, e.g. "./a/b/" and "./a/c/e/../../b" should
be the same dir, but memcmp() will report they are different dirs,
this will introduce the same dir be added twice or dead-loop
reference.
Now we have new method to compare two directories and can handle both
absolute path and relative path comparison, in addition to we already
have max depth 5 limitation, we can safely remove this limitation.
Moreover removing this limitation will make below two usage workable.
usage1: base-repos has relative path in the alternates
%>git clone --reference base-repos src dest
usage2: src2 has relative path to point src1, src1 has relative path
to point src
%>git clone src2 dest
Signed-off-by: Hui Wang <Hui.Wang@windriver.com>
---
sha1_file.c | 13 ++++---------
1 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index 18f7fb3..98fdb0a 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -329,15 +329,10 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
}
while (cp < ep && *cp != sep)
cp++;
- if (last != cp) {
- if (!is_absolute_path(last) && depth) {
- error("%s: ignoring relative alternate object store %s",
- relative_base, last);
- } else {
- link_alt_odb_entry(last, cp - last,
- relative_base, depth);
- }
- }
+ if (last != cp)
+ link_alt_odb_entry(last, cp - last,
+ relative_base, depth);
+
while (cp < ep && *cp == sep)
cp++;
last = cp;
--
1.6.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 5/5] t5710: add testcase for multi-level relative alternates
2011-09-06 10:24 ` [PATCH v2 4/5] sha1_file: remove relative entries limitation Wang Hui
@ 2011-09-06 10:24 ` Wang Hui
0 siblings, 0 replies; 11+ messages in thread
From: Wang Hui @ 2011-09-06 10:24 UTC (permalink / raw)
To: gitster, git, tali
From: Hui Wang <Hui.Wang@windriver.com>
Since we removed "relative alternates only possible for current dir"
limitation, it is needed to change an existing testcase to make it
pass for the relative path at the second level alternates.
Add a new testcase to make it pass when it work at a 5-level relative
alternates repository and make it fail when it work at a 6-level
relative alternates repository.
Signed-off-by: Hui Wang <Hui.Wang@windriver.com>
---
t/t5710-info-alternate.sh | 21 +++++++++++++++++++--
1 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh
index ef7127c..a606a94 100755
--- a/t/t5710-info-alternate.sh
+++ b/t/t5710-info-alternate.sh
@@ -102,9 +102,26 @@ test_valid_repo'
cd "$base_dir"
test_expect_success \
- 'that relative alternate is only possible for current dir' '
+ 'that relative alternate is possible for none current dir' '
cd D &&
- ! (test_valid_repo)
+ test_valid_repo
+'
+
+cd "$base_dir"
+
+test_expect_success 'allow maxium 5 level relative alternate' \
+'echo "" > A/.git/objects/info/alternates &&
+echo "../../../A/.git/objects" > B/.git/objects/info/alternates &&
+echo "../../../B/.git/objects" > C/.git/objects/info/alternates &&
+echo "../../../C/.git/objects" > D/.git/objects/info/alternates &&
+echo "../../../D/.git/objects" > E/.git/objects/info/alternates &&
+echo "../../../E/.git/objects" > F/.git/objects/info/alternates &&
+echo "../../../F/.git/objects" > G/.git/objects/info/alternates &&
+cd F &&
+test_valid_repo &&
+cd ../G &&
+git fsck --full > fsck.err 2>&1 &&
+test `wc -l < fsck.err` != 0
'
cd "$base_dir"
--
1.6.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/5] sha1_file: remove a buggy value setting
2011-09-06 10:24 ` [PATCH v2 2/5] sha1_file: remove a buggy value setting Wang Hui
2011-09-06 10:24 ` [PATCH v2 3/5] sha1_file: improve directories comparison method Wang Hui
@ 2011-09-06 16:26 ` Junio C Hamano
2011-09-07 9:55 ` wanghui
1 sibling, 1 reply; 11+ messages in thread
From: Junio C Hamano @ 2011-09-06 16:26 UTC (permalink / raw)
To: Wang Hui; +Cc: git, tali
Wang Hui <Hui.Wang@windriver.com> writes:
> From: Hui Wang <Hui.Wang@windriver.com>
>
> The ent->base[] is a character array, it has pfxlen characters from
> position 0 to (pfxlen-1) to contain an alt object dir name, the
> position pfxlen should be the string terminating character '\0' and
> is deliberately set to '\0' at the previous code line. The position
> (pfxlen+1) is given to ent->name.
Correct. Do you understand why?
We temporarily NUL terminate the ent->base[] so that we can give it to
is_directory() to see if that is a directory, but the invariants for a
alternate_object_database instance after it is properly initialized by
this function are to have:
- the directory name followed by a slash in the base[] array;
- the name pointer pointing at one byte beyond the slash;
- name[2] filled with a slash; and
- name[41] terminated with NUL.
Later, has_loose_object_nonlocal() calls fill_sha1_path() with the name
pointer to fill name[0..1, 3..40] with the hexadecimal representation of
the object name, which would result in base[] array to have the pathname
for a loose object found in that alternate. The same thing happens in
open_sha1_file() to read from a loose object in an alternate.
And you are breaking one of the above invariants by removing that slash
after the directory name. These callers of fill_sha1_path() will see the
directory name, your NUL, two hex, slash, and 38 hex in base[].
How would the code even work with your patch?
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 3/5] sha1_file: improve directories comparison method
2011-09-06 10:24 ` [PATCH v2 3/5] sha1_file: improve directories comparison method Wang Hui
2011-09-06 10:24 ` [PATCH v2 4/5] sha1_file: remove relative entries limitation Wang Hui
@ 2011-09-06 16:32 ` Junio C Hamano
1 sibling, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2011-09-06 16:32 UTC (permalink / raw)
To: Wang Hui; +Cc: git, tali
Wang Hui <Hui.Wang@windriver.com> writes:
> From: Hui Wang <Hui.Wang@windriver.com>
>
> In the past, to check if two directory paths are same, we use memcmp()
> to directly compare their path strings, this method can't get an
> accurate result if paths include ".." or "." or redundant slash, e.g.
> current dir is /, "/a/b/c", "/a/b//c/d/e/../.." and "./a/b/f/../c"
> should be the same dir, but current method will identify they are
> different.
>
> Now add a global function is_same_directory() to replace the old
> memcmp() method, this function will change two input paths to real
> path first, then normalized them and compare them.
I do not like this patch _at all_. While it may result in correct result
if you _always_ make it absolute before comparing two entities, if you
will be storing the normalized result after running the comparison anyway,
and if you are comparing against the existing and supposedly already
normalized entities with a new candidate, why would anybody sane would
want to keep paying for the normalization cost at such a low level?
IOW, you are proposing to do:
given a new candidate;
for existing entities:
normalize existing
normalize candiate
compare the above two
if they are equal:
ignore
if no match found
add the normalized candidate to the list
Wouldn't it make much more sense to do this:
given a new candidate;
normalize it
for existing entities:
compare existing and normalized candidate
there is no point in normalizing the existing one!
if they are equal:
ignore
if no match found
add the normalized candidate to the list
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check
2011-09-06 10:24 ` [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check Wang Hui
2011-09-06 10:24 ` [PATCH v2 2/5] sha1_file: remove a buggy value setting Wang Hui
@ 2011-09-06 16:59 ` Junio C Hamano
2011-09-07 10:24 ` wanghui
1 sibling, 1 reply; 11+ messages in thread
From: Junio C Hamano @ 2011-09-06 16:59 UTC (permalink / raw)
To: Wang Hui; +Cc: git, tali
Wang Hui <Hui.Wang@windriver.com> writes:
> From: Hui Wang <Hui.Wang@windriver.com>
>
> This variable check is always true, so it is redundant and need to be
> removed.
>
> We can't remove the init value for this variable, since removing
> it will introduce building warning:
> 'base_len' may be used uninitialized in this function.
If we are into cleaning things up, we should instead notice and say "yuck"
to the repeated "is entry is absolute and relative base is given" check.
Wouldn't something like this makes things easier to follow and also avoids
the "when does the path normalized and made absolute" issue?
Completely untested and I may have off-by-one errors and such, but I think
you would get the idea...
sha1_file.c | 29 ++++++++++++-----------------
1 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index e002056..26aa3be 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -248,27 +248,22 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
const char *objdir = get_object_directory();
struct alternate_object_database *ent;
struct alternate_object_database *alt;
- /* 43 = 40-byte + 2 '/' + terminating NUL */
- int pfxlen = len;
- int entlen = pfxlen + 43;
- int base_len = -1;
+ int pfxlen, entlen;
+ struct strbuf pathbuf = STRBUF_INIT;
if (!is_absolute_path(entry) && relative_base) {
- /* Relative alt-odb */
- if (base_len < 0)
- base_len = strlen(relative_base) + 1;
- entlen += base_len;
- pfxlen += base_len;
+ strbuf_addstr(&pathbuf, relative_base);
+ strbuf_addch(&pathbuf, '/');
}
- ent = xmalloc(sizeof(*ent) + entlen);
+ strbuf_add(&pathbuf, entry, len);
+ normalize_path_copy(pathbuf.buf, pathbuf.buf);
+ strbuf_setlen(&pathbuf, strlen(pathbuf.buf));
- if (!is_absolute_path(entry) && relative_base) {
- memcpy(ent->base, relative_base, base_len - 1);
- ent->base[base_len - 1] = '/';
- memcpy(ent->base + base_len, entry, len);
- }
- else
- memcpy(ent->base, entry, pfxlen);
+ pfxlen = pathbuf.len;
+ entlen = pfxlen + 43; /* '/' + 2 hex + '/' + 38 hex + NUL */
+ ent = xmalloc(sizeof(*ent) + entlen);
+ memcpy(ent->base, pathbuf.buf, pfxlen);
+ strbuf_release(&pathbuf);
ent->name = ent->base + pfxlen + 1;
ent->base[pfxlen + 3] = '/';
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/5] sha1_file: remove a buggy value setting
2011-09-06 16:26 ` [PATCH v2 2/5] sha1_file: remove a buggy value setting Junio C Hamano
@ 2011-09-07 9:55 ` wanghui
0 siblings, 0 replies; 11+ messages in thread
From: wanghui @ 2011-09-07 9:55 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, tali
Junio C Hamano wrote:
> Wang Hui <Hui.Wang@windriver.com> writes:
>
>
>> From: Hui Wang <Hui.Wang@windriver.com>
>>
>> The ent->base[] is a character array, it has pfxlen characters from
>> position 0 to (pfxlen-1) to contain an alt object dir name, the
>> position pfxlen should be the string terminating character '\0' and
>> is deliberately set to '\0' at the previous code line. The position
>> (pfxlen+1) is given to ent->name.
>>
>
> Correct. Do you understand why?
>
> We temporarily NUL terminate the ent->base[] so that we can give it to
> is_directory() to see if that is a directory, but the invariants for a
> alternate_object_database instance after it is properly initialized by
> this function are to have:
>
> - the directory name followed by a slash in the base[] array;
> - the name pointer pointing at one byte beyond the slash;
> - name[2] filled with a slash; and
> - name[41] terminated with NUL.
>
> Later, has_loose_object_nonlocal() calls fill_sha1_path() with the name
> pointer to fill name[0..1, 3..40] with the hexadecimal representation of
> the object name, which would result in base[] array to have the pathname
> for a loose object found in that alternate. The same thing happens in
> open_sha1_file() to read from a loose object in an alternate.
>
> And you are breaking one of the above invariants by removing that slash
> after the directory name. These callers of fill_sha1_path() will see the
> directory name, your NUL, two hex, slash, and 38 hex in base[].
>
>
Understand now, thanks for your explanation.
> How would the code even work with your patch?
>
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check
2011-09-06 16:59 ` [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check Junio C Hamano
@ 2011-09-07 10:24 ` wanghui
0 siblings, 0 replies; 11+ messages in thread
From: wanghui @ 2011-09-07 10:24 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, tali
Junio C Hamano wrote:
> Wang Hui <Hui.Wang@windriver.com> writes:
>
>
>> From: Hui Wang <Hui.Wang@windriver.com>
>>
>> This variable check is always true, so it is redundant and need to be
>> removed.
>>
>> We can't remove the init value for this variable, since removing
>> it will introduce building warning:
>> 'base_len' may be used uninitialized in this function.
>>
>
> If we are into cleaning things up, we should instead notice and say "yuck"
> to the repeated "is entry is absolute and relative base is given" check.
>
> Wouldn't something like this makes things easier to follow and also avoids
> the "when does the path normalized and made absolute" issue?
>
> Completely untested and I may have off-by-one errors and such, but I think
> you would get the idea...
>
>
Yes, i got the idea, and some errors are pointed out below. I will
prepare a V3 patch basing on it.
> sha1_file.c | 29 ++++++++++++-----------------
> 1 files changed, 12 insertions(+), 17 deletions(-)
>
> diff --git a/sha1_file.c b/sha1_file.c
> index e002056..26aa3be 100644
> --- a/sha1_file.c
> +++ b/sha1_file.c
> @@ -248,27 +248,22 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
> const char *objdir = get_object_directory();
> struct alternate_object_database *ent;
> struct alternate_object_database *alt;
> - /* 43 = 40-byte + 2 '/' + terminating NUL */
> - int pfxlen = len;
> - int entlen = pfxlen + 43;
> - int base_len = -1;
> + int pfxlen, entlen;
> + struct strbuf pathbuf = STRBUF_INIT;
>
> if (!is_absolute_path(entry) && relative_base) {
> - /* Relative alt-odb */
> - if (base_len < 0)
> - base_len = strlen(relative_base) + 1;
> - entlen += base_len;
> - pfxlen += base_len;
> + strbuf_addstr(&pathbuf, relative_base);
>
s/relative_base/real_path(relative_base)/ is better, since
normalize_path_copy is not good at handle relative path. e.g. ".
./objects/../../test2/objects" will be normalized to "objects"
> + strbuf_addch(&pathbuf, '/');
> }
> - ent = xmalloc(sizeof(*ent) + entlen);
> + strbuf_add(&pathbuf, entry, len);
> + normalize_path_copy(pathbuf.buf, pathbuf.buf);
>
if pathbuf.buf[strlen(pathbuf.buf)] is '/', remove it. this can avoid to
get a wrong result when comparing "/a/b" with "/a/b/".
> + strbuf_setlen(&pathbuf, strlen(pathbuf.buf));
>
above line can be removed, since we will release pathbuf soon.
>
> - if (!is_absolute_path(entry) && relative_base) {
> - memcpy(ent->base, relative_base, base_len - 1);
> - ent->base[base_len - 1] = '/';
> - memcpy(ent->base + base_len, entry, len);
> - }
> - else
> - memcpy(ent->base, entry, pfxlen);
> + pfxlen = pathbuf.len;
> + entlen = pfxlen + 43; /* '/' + 2 hex + '/' + 38 hex + NUL */
> + ent = xmalloc(sizeof(*ent) + entlen);
> + memcpy(ent->base, pathbuf.buf, pfxlen);
> + strbuf_release(&pathbuf);
>
> ent->name = ent->base + pfxlen + 1;
> ent->base[pfxlen + 3] = '/';
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-09-07 17:29 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-06 10:24 [PATCH v2 0/5] sha1_file: remove only current repository can have relative path limitation Wang Hui
2011-09-06 10:24 ` [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check Wang Hui
2011-09-06 10:24 ` [PATCH v2 2/5] sha1_file: remove a buggy value setting Wang Hui
2011-09-06 10:24 ` [PATCH v2 3/5] sha1_file: improve directories comparison method Wang Hui
2011-09-06 10:24 ` [PATCH v2 4/5] sha1_file: remove relative entries limitation Wang Hui
2011-09-06 10:24 ` [PATCH v2 5/5] t5710: add testcase for multi-level relative alternates Wang Hui
2011-09-06 16:32 ` [PATCH v2 3/5] sha1_file: improve directories comparison method Junio C Hamano
2011-09-06 16:26 ` [PATCH v2 2/5] sha1_file: remove a buggy value setting Junio C Hamano
2011-09-07 9:55 ` wanghui
2011-09-06 16:59 ` [PATCH v2 1/5] sha1_file cleanup: remove redundant variable check Junio C Hamano
2011-09-07 10:24 ` wanghui
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).