From 7c7fcdae0e112f56188f13971acae26470287dd3 Mon Sep 17 00:00:00 2001 From: Jakob Pfender Date: Mon, 4 Apr 2011 16:20:09 +0200 Subject: [PATCH 1/3] index.h: Add IDXENTRY flags needed for index operations Add several IDXENTRY flags that need to be checked in order to properly implement update-index --refresh. --- include/git2/index.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/include/git2/index.h b/include/git2/index.h index 599512f8a..8a84f507b 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -44,6 +44,46 @@ GIT_BEGIN_DECL #define GIT_IDXENTRY_VALID (0x8000) #define GIT_IDXENTRY_STAGESHIFT 12 +/* + * Flags are divided into two parts: in-memory flags and + * on-disk ones. Flags in GIT_IDXENTRY_EXTENDED_FLAGS + * will get saved on-disk. + * + * In-memory only flags: + */ +#define GIT_IDXENTRY_UPDATE (1 << 16) +#define GIT_IDXENTRY_REMOVE (1 << 17) +#define GIT_IDXENTRY_UPTODATE (1 << 18) +#define GIT_IDXENTRY_ADDED (1 << 19) + +#define GIT_IDXENTRY_HASHED (1 << 20) +#define GIT_IDXENTRY_UNHASHED (1 << 21) +#define GIT_IDXENTRY_WT_REMOVE (1 << 22) /* remove in work directory */ +#define GIT_IDXENTRY_CONFLICTED (1 << 23) + +#define GIT_IDXENTRY_UNPACKED (1 << 24) +#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 25) + +/* + * Extended on-disk flags: + */ +#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 29) +#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 30) +/* GIT_IDXENTRY_EXTENDED2 is for future extension */ +#define GIT_IDXENTRY_EXTENDED2 (1 << 31) + +#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE) + +/* + * Safeguard to avoid saving wrong flags: + * - GIT_IDXENTRY_EXTENDED2 won't get saved until its semantic is known + * - Bits in 0x0000FFFF have been saved in flags already + * - Bits in 0x003F0000 are currently in-memory flags + */ +#if GIT_IDXENTRY_EXTENDED_FLAGS & 0x803FFFFF +#error "GIT_IDXENTRY_EXTENDED_FLAGS out of range" +#endif + /** Time used in a git index entry */ typedef struct { git_time_t seconds; From a5a546b36c184890dee09bd2bd92836c60eec122 Mon Sep 17 00:00:00 2001 From: Jakob Pfender Date: Thu, 7 Apr 2011 16:53:50 +0200 Subject: [PATCH 2/3] index.h: Correct values for extended flags As libgit2 separates an index entry's 32-bit flag into two 16-bit values flags and flags_extended, the values of flags_extended need to be adjusted. --- include/git2/index.h | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/include/git2/index.h b/include/git2/index.h index 8a84f507b..d69e58b1c 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -51,39 +51,29 @@ GIT_BEGIN_DECL * * In-memory only flags: */ -#define GIT_IDXENTRY_UPDATE (1 << 16) -#define GIT_IDXENTRY_REMOVE (1 << 17) -#define GIT_IDXENTRY_UPTODATE (1 << 18) -#define GIT_IDXENTRY_ADDED (1 << 19) +#define GIT_IDXENTRY_UPDATE (1 << 0) +#define GIT_IDXENTRY_REMOVE (1 << 1) +#define GIT_IDXENTRY_UPTODATE (1 << 2) +#define GIT_IDXENTRY_ADDED (1 << 3) -#define GIT_IDXENTRY_HASHED (1 << 20) -#define GIT_IDXENTRY_UNHASHED (1 << 21) -#define GIT_IDXENTRY_WT_REMOVE (1 << 22) /* remove in work directory */ -#define GIT_IDXENTRY_CONFLICTED (1 << 23) +#define GIT_IDXENTRY_HASHED (1 << 4) +#define GIT_IDXENTRY_UNHASHED (1 << 5) +#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */ +#define GIT_IDXENTRY_CONFLICTED (1 << 7) -#define GIT_IDXENTRY_UNPACKED (1 << 24) -#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 25) +#define GIT_IDXENTRY_UNPACKED (1 << 8) +#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9) /* * Extended on-disk flags: */ -#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 29) -#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 30) +#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13) +#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14) /* GIT_IDXENTRY_EXTENDED2 is for future extension */ -#define GIT_IDXENTRY_EXTENDED2 (1 << 31) +#define GIT_IDXENTRY_EXTENDED2 (1 << 15) #define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE) -/* - * Safeguard to avoid saving wrong flags: - * - GIT_IDXENTRY_EXTENDED2 won't get saved until its semantic is known - * - Bits in 0x0000FFFF have been saved in flags already - * - Bits in 0x003F0000 are currently in-memory flags - */ -#if GIT_IDXENTRY_EXTENDED_FLAGS & 0x803FFFFF -#error "GIT_IDXENTRY_EXTENDED_FLAGS out of range" -#endif - /** Time used in a git index entry */ typedef struct { git_time_t seconds; From fd279b262df31c9a5d88db78e9e9a6de07e62979 Mon Sep 17 00:00:00 2001 From: Jakob Pfender Date: Thu, 7 Apr 2011 16:58:42 +0200 Subject: [PATCH 3/3] index.c: Correctly check whether index contains extended entries Although write_index() supports writing extended header versions for index, this was never done as there was no check for extended index entries. Introduce function is_index_extended() that checks whether an index contains extended entries and check whether an index is extended before writing it to disk, adjusting its version number if necessary. --- src/index.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/index.c b/src/index.c index 6a31dd5cb..6a67e9c7c 100644 --- a/src/index.c +++ b/src/index.c @@ -101,6 +101,7 @@ static int read_tree(git_index *index, const char *buffer, size_t buffer_size); static git_index_tree *read_tree_internal(const char **, const char *, git_index_tree *); static int parse_index(git_index *index, const char *buffer, size_t buffer_size); +static int is_index_extended(git_index *index); static void sort_index(git_index *index); static int write_index(git_index *index, git_filebuf *file); @@ -674,6 +675,24 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) return GIT_SUCCESS; } +static int is_index_extended(git_index *index) +{ + unsigned int i, extended; + + extended = 0; + + for (i = 0; i < index->entries.length; ++i) { + git_index_entry *entry; + entry = git_vector_get(&index->entries, i); + entry->flags &= ~GIT_IDXENTRY_EXTENDED; + if (entry->flags_extended & GIT_IDXENTRY_EXTENDED_FLAGS) { + extended++; + entry->flags |= GIT_IDXENTRY_EXTENDED; + } + } + return extended; +} + static int write_disk_entry(git_filebuf *file, git_index_entry *entry) { struct entry_short *ondisk; @@ -742,12 +761,14 @@ static int write_index(git_index *index, git_filebuf *file) struct index_header header; - int is_extended = 1; + int is_extended; assert(index && file); + is_extended = is_index_extended(index); + header.signature = htonl(INDEX_HEADER_SIG); - header.version = htonl(is_extended ? INDEX_VERSION_NUMBER : INDEX_VERSION_NUMBER_EXT); + header.version = htonl(is_extended ? INDEX_VERSION_NUMBER_EXT : INDEX_VERSION_NUMBER); header.entry_count = htonl(index->entries.length); git_filebuf_write(file, &header, sizeof(struct index_header));