Skip to content

Commit 92e0d91

Browse files
committed
Sync with 1.8.1 maintenance track
* maint-1.8.1: Start preparing for 1.8.1.6 git-tag(1): we tag HEAD by default Fix revision walk for commits with the same dates t2003: work around path mangling issue on Windows pack-refs: add fully-peeled trait pack-refs: write peeled entry for non-tags use parse_object_or_die instead of die("bad object") avoid segfaults on parse_object failure entry: fix filter lookup t2003: modernize style name-hash.c: fix endless loop with core.ignorecase=true
2 parents 40a0f84 + 072dda6 commit 92e0d91

19 files changed

+462
-164
lines changed

Documentation/RelNotes/1.8.1.6.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
Git 1.8.1.6 Release Notes
2+
=========================
3+
4+
Fixes since v1.8.1.5
5+
--------------------
6+
7+
* The code to keep track of what directory names are known to Git on
8+
platforms with case insensitive filesystems can get confused upon a
9+
hash collision between these pathnames and looped forever.
10+
11+
* When the "--prefix" option is used to "checkout-index", the code
12+
did not pick the correct output filter based on the attribute
13+
setting.
14+
15+
* Annotated tags outside refs/tags/ hierarchy were not advertised
16+
correctly to the ls-remote and fetch with recent version of Git.
17+
18+
* The logic used by "git diff -M --stat" to shorten the names of
19+
files before and after a rename did not work correctly when the
20+
common prefix and suffix between the two filenames overlapped.
21+
22+
* "git update-index -h" did not do the usual "-h(elp)" thing.
23+
24+
* perl/Git.pm::cat_blob slurped everything in core only to write it
25+
out to a file descriptor, which was not a very smart thing to do.
26+
27+
* The SSL peer verification done by "git imap-send" did not ask for
28+
Server Name Indication (RFC 4366), failing to connect SSL/TLS
29+
sites that serve multiple hostnames on a single IP.
30+
31+
* "git bundle verify" did not say "records a complete history" for a
32+
bundle that does not have any prerequisites.
33+
34+
Also contains various documentation fixes.

Documentation/git-tag.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ This option is only applicable when listing tags without annotation lines.
126126
linkgit:git-check-ref-format[1]. Some of these checks
127127
may restrict the characters allowed in a tag name.
128128

129+
<commit>::
130+
<object>::
131+
The object that the new tag will refer to, usually a commit.
132+
Defaults to HEAD.
133+
134+
129135
CONFIGURATION
130136
-------------
131137
By default, 'git tag' in sign-with-default mode (-s) will use your

builtin/grep.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -820,9 +820,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
820820
unsigned char sha1[20];
821821
/* Is it a rev? */
822822
if (!get_sha1(arg, sha1)) {
823-
struct object *object = parse_object(sha1);
824-
if (!object)
825-
die(_("bad object %s"), arg);
823+
struct object *object = parse_object_or_die(sha1, arg);
826824
if (!seen_dashdash)
827825
verify_non_filename(prefix, arg);
828826
add_object_array(object, arg, &list);

builtin/prune.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
149149
const char *name = *argv++;
150150

151151
if (!get_sha1(name, sha1)) {
152-
struct object *object = parse_object(sha1);
153-
if (!object)
154-
die("bad object: %s", name);
152+
struct object *object = parse_object_or_die(sha1, name);
155153
add_pending_object(&revs, object, "");
156154
}
157155
else

bundle.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,12 @@ int create_bundle(struct bundle_header *header, const char *path,
279279
if (buf.len > 0 && buf.buf[0] == '-') {
280280
write_or_die(bundle_fd, buf.buf, buf.len);
281281
if (!get_sha1_hex(buf.buf + 1, sha1)) {
282-
struct object *object = parse_object(sha1);
282+
struct object *object = parse_object_or_die(sha1, buf.buf);
283283
object->flags |= UNINTERESTING;
284284
add_pending_object(&revs, object, xstrdup(buf.buf));
285285
}
286286
} else if (!get_sha1_hex(buf.buf, sha1)) {
287-
struct object *object = parse_object(sha1);
287+
struct object *object = parse_object_or_die(sha1, buf.buf);
288288
object->flags |= SHOWN;
289289
}
290290
}
@@ -361,7 +361,7 @@ int create_bundle(struct bundle_header *header, const char *path,
361361
* end up triggering "empty bundle"
362362
* error.
363363
*/
364-
obj = parse_object(sha1);
364+
obj = parse_object_or_die(sha1, e->name);
365365
obj->flags |= SHOWN;
366366
add_pending_object(&revs, obj, e->name);
367367
}

cache.h

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ struct cache_entry {
131131
unsigned int ce_namelen;
132132
unsigned char sha1[20];
133133
struct cache_entry *next;
134-
struct cache_entry *dir_next;
135134
char name[FLEX_ARRAY]; /* more */
136135
};
137136

@@ -267,25 +266,15 @@ struct index_state {
267266
unsigned name_hash_initialized : 1,
268267
initialized : 1;
269268
struct hash_table name_hash;
269+
struct hash_table dir_hash;
270270
};
271271

272272
extern struct index_state the_index;
273273

274274
/* Name hashing */
275275
extern void add_name_hash(struct index_state *istate, struct cache_entry *ce);
276-
/*
277-
* We don't actually *remove* it, we can just mark it invalid so that
278-
* we won't find it in lookups.
279-
*
280-
* Not only would we have to search the lists (simple enough), but
281-
* we'd also have to rehash other hash buckets in case this makes the
282-
* hash bucket empty (common). So it's much better to just mark
283-
* it.
284-
*/
285-
static inline void remove_name_hash(struct cache_entry *ce)
286-
{
287-
ce->ce_flags |= CE_UNHASHED;
288-
}
276+
extern void remove_name_hash(struct index_state *istate, struct cache_entry *ce);
277+
extern void free_name_hash(struct index_state *istate);
289278

290279

291280
#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS

entry.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
145145
struct stat st;
146146

147147
if (ce_mode_s_ifmt == S_IFREG) {
148-
struct stream_filter *filter = get_stream_filter(path, ce->sha1);
148+
struct stream_filter *filter = get_stream_filter(ce->name, ce->sha1);
149149
if (filter &&
150150
!streaming_write_entry(ce, path, filter,
151151
state, to_tempfile,

name-hash.c

Lines changed: 139 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -32,38 +32,96 @@ static unsigned int hash_name(const char *name, int namelen)
3232
return hash;
3333
}
3434

35-
static void hash_index_entry_directories(struct index_state *istate, struct cache_entry *ce)
35+
struct dir_entry {
36+
struct dir_entry *next;
37+
struct dir_entry *parent;
38+
struct cache_entry *ce;
39+
int nr;
40+
unsigned int namelen;
41+
};
42+
43+
static struct dir_entry *find_dir_entry(struct index_state *istate,
44+
const char *name, unsigned int namelen)
45+
{
46+
unsigned int hash = hash_name(name, namelen);
47+
struct dir_entry *dir;
48+
49+
for (dir = lookup_hash(hash, &istate->dir_hash); dir; dir = dir->next)
50+
if (dir->namelen == namelen &&
51+
!strncasecmp(dir->ce->name, name, namelen))
52+
return dir;
53+
return NULL;
54+
}
55+
56+
static struct dir_entry *hash_dir_entry(struct index_state *istate,
57+
struct cache_entry *ce, int namelen)
3658
{
3759
/*
3860
* Throw each directory component in the hash for quick lookup
3961
* during a git status. Directory components are stored with their
4062
* closing slash. Despite submodules being a directory, they never
4163
* reach this point, because they are stored without a closing slash
42-
* in the cache.
64+
* in index_state.name_hash (as ordinary cache_entries).
4365
*
44-
* Note that the cache_entry stored with the directory does not
45-
* represent the directory itself. It is a pointer to an existing
46-
* filename, and its only purpose is to represent existence of the
47-
* directory in the cache. It is very possible multiple directory
48-
* hash entries may point to the same cache_entry.
66+
* Note that the cache_entry stored with the dir_entry merely
67+
* supplies the name of the directory (up to dir_entry.namelen). We
68+
* track the number of 'active' files in a directory in dir_entry.nr,
69+
* so we can tell if the directory is still relevant, e.g. for git
70+
* status. However, if cache_entries are removed, we cannot pinpoint
71+
* an exact cache_entry that's still active. It is very possible that
72+
* multiple dir_entries point to the same cache_entry.
4973
*/
50-
unsigned int hash;
51-
void **pos;
74+
struct dir_entry *dir;
75+
76+
/* get length of parent directory */
77+
while (namelen > 0 && !is_dir_sep(ce->name[namelen - 1]))
78+
namelen--;
79+
if (namelen <= 0)
80+
return NULL;
81+
82+
/* lookup existing entry for that directory */
83+
dir = find_dir_entry(istate, ce->name, namelen);
84+
if (!dir) {
85+
/* not found, create it and add to hash table */
86+
void **pdir;
87+
unsigned int hash = hash_name(ce->name, namelen);
5288

53-
const char *ptr = ce->name;
54-
while (*ptr) {
55-
while (*ptr && *ptr != '/')
56-
++ptr;
57-
if (*ptr == '/') {
58-
++ptr;
59-
hash = hash_name(ce->name, ptr - ce->name);
60-
pos = insert_hash(hash, ce, &istate->name_hash);
61-
if (pos) {
62-
ce->dir_next = *pos;
63-
*pos = ce;
64-
}
89+
dir = xcalloc(1, sizeof(struct dir_entry));
90+
dir->namelen = namelen;
91+
dir->ce = ce;
92+
93+
pdir = insert_hash(hash, dir, &istate->dir_hash);
94+
if (pdir) {
95+
dir->next = *pdir;
96+
*pdir = dir;
6597
}
98+
99+
/* recursively add missing parent directories */
100+
dir->parent = hash_dir_entry(istate, ce, namelen - 1);
66101
}
102+
return dir;
103+
}
104+
105+
static void add_dir_entry(struct index_state *istate, struct cache_entry *ce)
106+
{
107+
/* Add reference to the directory entry (and parents if 0). */
108+
struct dir_entry *dir = hash_dir_entry(istate, ce, ce_namelen(ce));
109+
while (dir && !(dir->nr++))
110+
dir = dir->parent;
111+
}
112+
113+
static void remove_dir_entry(struct index_state *istate, struct cache_entry *ce)
114+
{
115+
/*
116+
* Release reference to the directory entry (and parents if 0).
117+
*
118+
* Note: we do not remove / free the entry because there's no
119+
* hash.[ch]::remove_hash and dir->next may point to other entries
120+
* that are still valid, so we must not free the memory.
121+
*/
122+
struct dir_entry *dir = hash_dir_entry(istate, ce, ce_namelen(ce));
123+
while (dir && dir->nr && !(--dir->nr))
124+
dir = dir->parent;
67125
}
68126

69127
static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
@@ -74,16 +132,16 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
74132
if (ce->ce_flags & CE_HASHED)
75133
return;
76134
ce->ce_flags |= CE_HASHED;
77-
ce->next = ce->dir_next = NULL;
135+
ce->next = NULL;
78136
hash = hash_name(ce->name, ce_namelen(ce));
79137
pos = insert_hash(hash, ce, &istate->name_hash);
80138
if (pos) {
81139
ce->next = *pos;
82140
*pos = ce;
83141
}
84142

85-
if (ignore_case)
86-
hash_index_entry_directories(istate, ce);
143+
if (ignore_case && !(ce->ce_flags & CE_UNHASHED))
144+
add_dir_entry(istate, ce);
87145
}
88146

89147
static void lazy_init_name_hash(struct index_state *istate)
@@ -99,11 +157,33 @@ static void lazy_init_name_hash(struct index_state *istate)
99157

100158
void add_name_hash(struct index_state *istate, struct cache_entry *ce)
101159
{
160+
/* if already hashed, add reference to directory entries */
161+
if (ignore_case && (ce->ce_flags & CE_STATE_MASK) == CE_STATE_MASK)
162+
add_dir_entry(istate, ce);
163+
102164
ce->ce_flags &= ~CE_UNHASHED;
103165
if (istate->name_hash_initialized)
104166
hash_index_entry(istate, ce);
105167
}
106168

169+
/*
170+
* We don't actually *remove* it, we can just mark it invalid so that
171+
* we won't find it in lookups.
172+
*
173+
* Not only would we have to search the lists (simple enough), but
174+
* we'd also have to rehash other hash buckets in case this makes the
175+
* hash bucket empty (common). So it's much better to just mark
176+
* it.
177+
*/
178+
void remove_name_hash(struct index_state *istate, struct cache_entry *ce)
179+
{
180+
/* if already hashed, release reference to directory entries */
181+
if (ignore_case && (ce->ce_flags & CE_STATE_MASK) == CE_HASHED)
182+
remove_dir_entry(istate, ce);
183+
184+
ce->ce_flags |= CE_UNHASHED;
185+
}
186+
107187
static int slow_same_name(const char *name1, int len1, const char *name2, int len2)
108188
{
109189
if (len1 != len2)
@@ -137,18 +217,7 @@ static int same_name(const struct cache_entry *ce, const char *name, int namelen
137217
if (!icase)
138218
return 0;
139219

140-
/*
141-
* If the entry we're comparing is a filename (no trailing slash), then compare
142-
* the lengths exactly.
143-
*/
144-
if (name[namelen - 1] != '/')
145-
return slow_same_name(name, namelen, ce->name, len);
146-
147-
/*
148-
* For a directory, we point to an arbitrary cache_entry filename. Just
149-
* make sure the directory portion matches.
150-
*/
151-
return slow_same_name(name, namelen, ce->name, namelen < len ? namelen : len);
220+
return slow_same_name(name, namelen, ce->name, len);
152221
}
153222

154223
struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int icase)
@@ -164,27 +233,54 @@ struct cache_entry *index_name_exists(struct index_state *istate, const char *na
164233
if (same_name(ce, name, namelen, icase))
165234
return ce;
166235
}
167-
if (icase && name[namelen - 1] == '/')
168-
ce = ce->dir_next;
169-
else
170-
ce = ce->next;
236+
ce = ce->next;
171237
}
172238

173239
/*
174-
* Might be a submodule. Despite submodules being directories,
240+
* When looking for a directory (trailing '/'), it might be a
241+
* submodule or a directory. Despite submodules being directories,
175242
* they are stored in the name hash without a closing slash.
176-
* When ignore_case is 1, directories are stored in the name hash
177-
* with their closing slash.
243+
* When ignore_case is 1, directories are stored in a separate hash
244+
* table *with* their closing slash.
178245
*
179246
* The side effect of this storage technique is we have need to
247+
* lookup the directory in a separate hash table, and if not found
180248
* remove the slash from name and perform the lookup again without
181249
* the slash. If a match is made, S_ISGITLINK(ce->mode) will be
182250
* true.
183251
*/
184252
if (icase && name[namelen - 1] == '/') {
253+
struct dir_entry *dir = find_dir_entry(istate, name, namelen);
254+
if (dir && dir->nr)
255+
return dir->ce;
256+
185257
ce = index_name_exists(istate, name, namelen - 1, icase);
186258
if (ce && S_ISGITLINK(ce->ce_mode))
187259
return ce;
188260
}
189261
return NULL;
190262
}
263+
264+
static int free_dir_entry(void *entry, void *unused)
265+
{
266+
struct dir_entry *dir = entry;
267+
while (dir) {
268+
struct dir_entry *next = dir->next;
269+
free(dir);
270+
dir = next;
271+
}
272+
return 0;
273+
}
274+
275+
void free_name_hash(struct index_state *istate)
276+
{
277+
if (!istate->name_hash_initialized)
278+
return;
279+
istate->name_hash_initialized = 0;
280+
if (ignore_case)
281+
/* free directory entries */
282+
for_each_hash(&istate->dir_hash, free_dir_entry, NULL);
283+
284+
free_hash(&istate->name_hash);
285+
free_hash(&istate->dir_hash);
286+
}

0 commit comments

Comments
 (0)