зеркало из https://github.com/microsoft/git.git
Make git-add behave more sensibly in a case-insensitive environment
This expands on the previous patch, and allows "git add" to sanely handle a filename that has changed case, keeping the case in the index constant, and avoiding aliases. In particular, if you have an index entry called "File", but the checked-out tree is case-corrupted and has an entry called "file" instead, doing a git add . (or naming "file" explicitly) will automatically notice that we have an alias, and will replace the name "file" with the existing index capitalization (ie "File"). However, if we actually have *both* a file called "File" and one called "file", and they don't have the same lstat() information (ie we're on a case-sensitive filesystem but have the "core.ignorecase" flag set), we will error out if we try to add them both. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
6835550def
Коммит
1102952b45
1
cache.h
1
cache.h
|
@ -133,6 +133,7 @@ struct cache_entry {
|
|||
#define CE_UPDATE (0x10000)
|
||||
#define CE_REMOVE (0x20000)
|
||||
#define CE_UPTODATE (0x40000)
|
||||
#define CE_ADDED (0x80000)
|
||||
|
||||
#define CE_HASHED (0x100000)
|
||||
#define CE_UNHASHED (0x200000)
|
||||
|
|
37
read-cache.c
37
read-cache.c
|
@ -429,6 +429,38 @@ static int index_name_pos_also_unmerged(struct index_state *istate,
|
|||
return pos;
|
||||
}
|
||||
|
||||
static int different_name(struct cache_entry *ce, struct cache_entry *alias)
|
||||
{
|
||||
int len = ce_namelen(ce);
|
||||
return ce_namelen(alias) != len || memcmp(ce->name, alias->name, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we add a filename that aliases in the cache, we will use the
|
||||
* name that we already have - but we don't want to update the same
|
||||
* alias twice, because that implies that there were actually two
|
||||
* different files with aliasing names!
|
||||
*
|
||||
* So we use the CE_ADDED flag to verify that the alias was an old
|
||||
* one before we accept it as
|
||||
*/
|
||||
static struct cache_entry *create_alias_ce(struct cache_entry *ce, struct cache_entry *alias)
|
||||
{
|
||||
int len;
|
||||
struct cache_entry *new;
|
||||
|
||||
if (alias->ce_flags & CE_ADDED)
|
||||
die("Will not add file alias '%s' ('%s' already exists in index)", ce->name, alias->name);
|
||||
|
||||
/* Ok, create the new entry using the name of the existing alias */
|
||||
len = ce_namelen(alias);
|
||||
new = xcalloc(1, cache_entry_size(len));
|
||||
memcpy(new->name, alias->name, len);
|
||||
copy_cache_entry(new, ce);
|
||||
free(ce);
|
||||
return new;
|
||||
}
|
||||
|
||||
int add_file_to_index(struct index_state *istate, const char *path, int verbose)
|
||||
{
|
||||
int size, namelen;
|
||||
|
@ -471,11 +503,14 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
|
|||
/* Nothing changed, really */
|
||||
free(ce);
|
||||
ce_mark_uptodate(alias);
|
||||
alias->ce_flags |= CE_ADDED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (index_path(ce->sha1, path, &st, 1))
|
||||
die("unable to index file %s", path);
|
||||
if (ignore_case && alias && different_name(ce, alias))
|
||||
ce = create_alias_ce(ce, alias);
|
||||
ce->ce_flags |= CE_ADDED;
|
||||
if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))
|
||||
die("unable to add %s to index",path);
|
||||
if (verbose)
|
||||
|
|
Загрузка…
Ссылка в новой задаче