From: Thomas Gummerer <t.gummerer@gmail.com>
To: git@vger.kernel.org
Cc: t.gummerer@gmail.com, gitster@pobox.com, tr@thomasrast.ch,
mhagger@alum.mit.edu, pclouds@gmail.com,
robin.rosenberg@dewire.com, sunshine@sunshineco.com,
ramsay@ramsay1.demon.co.uk
Subject: [PATCH v4 13/24] read-cache: read resolve-undo data
Date: Wed, 27 Nov 2013 13:00:48 +0100 [thread overview]
Message-ID: <1385553659-9928-14-git-send-email-t.gummerer@gmail.com> (raw)
In-Reply-To: <1385553659-9928-1-git-send-email-t.gummerer@gmail.com>
Make git read the resolve-undo data from the index.
Since the resolve-undo data is joined with the conflicts in
the ondisk format of the index file version 5, conflicts and
resolved data is read at the same time, and the resolve-undo
data are then converted to the in-memory format.
Helped-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
---
read-cache-v5.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 157 insertions(+), 3 deletions(-)
diff --git a/read-cache-v5.c b/read-cache-v5.c
index 9d8c8f0..a9c687f 100644
--- a/read-cache-v5.c
+++ b/read-cache-v5.c
@@ -1,5 +1,6 @@
#include "cache.h"
#include "read-cache.h"
+#include "string-list.h"
#include "resolve-undo.h"
#include "cache-tree.h"
#include "dir.h"
@@ -13,13 +14,18 @@ struct cache_header_v5 {
uint32_t hdr_nextension;
};
+struct extension_header {
+ char signature[4];
+ uint32_t size;
+ uint32_t crc;
+};
+
struct directory_entry {
struct directory_entry **sub;
struct directory_entry *next;
struct directory_entry *next_hash;
struct cache_entry *ce;
struct cache_entry *ce_last;
- uint32_t conflict_size;
uint32_t de_foffset;
uint32_t de_nsubtrees;
uint32_t de_nfiles;
@@ -42,7 +48,6 @@ struct conflict_entry {
uint32_t nfileconflicts;
struct conflict_part *entries;
uint32_t namelen;
- uint32_t pathlen;
char name[FLEX_ARRAY];
};
@@ -50,6 +55,12 @@ struct conflict_entry {
* Index File I/O
*****************************************************************/
+struct ondisk_conflict_part {
+ uint16_t flags;
+ uint16_t entry_mode;
+ unsigned char sha1[20];
+};
+
struct ondisk_cache_entry {
uint16_t flags;
uint16_t mode;
@@ -145,7 +156,7 @@ static int verify_hdr(void *mmap, unsigned long size)
hdr = mmap;
hdr_v5 = ptr_add(mmap, sizeof(*hdr));
/* Size of the header + the size of the extensionoffsets */
- header_size = sizeof(*hdr) + sizeof(*hdr_v5) + hdr_v5->hdr_nextension * 4;
+ header_size = sizeof(*hdr) + sizeof(*hdr_v5) + ntohl(hdr_v5->hdr_nextension) * 4;
/* Initialize crc */
filecrc = ptr_add(mmap, header_size);
if (!check_crc32(0, hdr, header_size, ntohl(*filecrc)))
@@ -279,6 +290,134 @@ static int read_entry(struct cache_entry **ce, char *pathname, size_t pathlen,
return 0;
}
+static struct conflict_part *conflict_part_from_ondisk(struct ondisk_conflict_part *ondisk)
+{
+ struct conflict_part *cp = xmalloc(sizeof(struct conflict_part));
+
+ cp->flags = ntoh_s(ondisk->flags);
+ cp->entry_mode = ntoh_s(ondisk->entry_mode);
+ hashcpy(cp->sha1, ondisk->sha1);
+ return cp;
+}
+
+struct conflict_entry *create_new_conflict(char *name, int len)
+{
+ struct conflict_entry *conflict_entry;
+
+ conflict_entry = xmalloc(conflict_entry_size(len));
+ memset(conflict_entry, 0, conflict_entry_size(len));
+ conflict_entry->namelen = len;
+ memcpy(conflict_entry->name, name, len);
+
+ return conflict_entry;
+}
+
+static void add_part_to_conflict_entry(struct conflict_entry *entry,
+ struct conflict_part *conflict_part)
+{
+
+ struct conflict_part *conflict_search;
+
+ entry->nfileconflicts++;
+ if (!entry->entries)
+ entry->entries = conflict_part;
+ else {
+ conflict_search = entry->entries;
+ while (conflict_search->next)
+ conflict_search = conflict_search->next;
+ conflict_search->next = conflict_part;
+ }
+}
+
+/*
+ * Read the resolve undo data on disk and convert it to the internal
+ * resolve undo format.
+ */
+static int read_resolve_undo(struct index_state *istate,
+ unsigned int offset, void *mmap,
+ unsigned int entries)
+{
+ int i, k;
+
+ for (i = 0; i < entries; i++) {
+ char *name;
+ unsigned int len, *nfileconflicts, nc;
+ uint32_t *crc;
+ struct ondisk_conflict_part *ondisk;
+ struct conflict_part *cp;
+ struct string_list_item *lost;
+ struct resolve_undo_info *ui;
+
+ name = ptr_add(mmap, offset);
+ len = strlen(name);
+ offset += len + 1;
+ nfileconflicts = ptr_add(mmap, offset);
+ nc = ntoh_l(*nfileconflicts);
+ offset += 4;
+
+ crc = ptr_add(mmap, offset +
+ nc * sizeof(struct ondisk_conflict_part));
+ if (!check_crc32(0, name, len + 1 + 4 +
+ nc * sizeof(struct ondisk_conflict_part),
+ ntoh_l(*crc)))
+ return -1;
+
+ ondisk = ptr_add(mmap, offset);
+ cp = conflict_part_from_ondisk(ondisk);
+ if (cp->flags & CONFLICT_CONFLICTED) {
+ offset += nc * sizeof(struct ondisk_conflict_part) + 4;
+ continue;
+ }
+ offset += sizeof(struct ondisk_conflict_part);
+ if (!istate->resolve_undo) {
+ istate->resolve_undo = xcalloc(1, sizeof(struct string_list));
+ istate->resolve_undo->strdup_strings = 1;
+ }
+
+ lost = string_list_insert(istate->resolve_undo, name);
+ if (!lost->util)
+ lost->util = xcalloc(1, sizeof(*ui));
+ ui = lost->util;
+ for (k = 0; k < 3; k++)
+ ui->mode[k] = 0;
+
+ ui->mode[conflict_stage(cp) - 1] = cp->entry_mode;
+ hashcpy(ui->sha1[conflict_stage(cp) - 1], cp->sha1);
+ for (k = 1; k < nc; k++) {
+ struct conflict_part *cp;
+
+ ondisk = ptr_add(mmap, offset);
+ cp = conflict_part_from_ondisk(ondisk);
+ ui->mode[conflict_stage(cp) - 1] = cp->entry_mode;
+ hashcpy(ui->sha1[conflict_stage(cp) - 1], cp->sha1);
+ offset += sizeof(struct ondisk_conflict_part);
+ }
+ offset += 4; /* crc */
+ }
+ return 0;
+}
+
+static int read_index_extension(struct index_state *istate,
+ void *mmap, unsigned int extoffset)
+{
+ struct extension_header *ehdr;
+
+ ehdr = ptr_add(mmap, extoffset);
+ /* -4 for the crc that's included in the struct */
+ if (!check_crc32(0, ptr_add(mmap, extoffset),
+ sizeof(*ehdr) - 4, ntoh_l(ehdr->crc)))
+ return -1;
+
+ switch (CACHE_EXT(ehdr->signature)) {
+ case CACHE_EXT_RESOLVE_UNDO:
+ if (read_resolve_undo(istate, extoffset + sizeof(*ehdr),
+ mmap, ntoh_l(ehdr->size)) < 0)
+ return -1;
+ break;
+ }
+ return 0;
+}
+
/*
* Read all file entries from the index. This function is recursive to get
* the ordering right. In the index file the entries are sorted def, abc/def,
@@ -404,6 +543,21 @@ static int read_index_v5(struct index_state *istate, void *mmap,
}
de = de->next;
}
+
+ if (!opts || opts->read_resolve_undo) {
+ for (i = 0; i < ntohl(hdr_v5->hdr_nextension); i++) {
+ /*
+ * After the index entry there is a number of
+ * extensions, which is written in the header.
+ * The extensions are prefixed by extension name
+ * (4-byte) and length of the extension (4-byte,
+ * usually the number of entries in that section)
+ * in network byte order
+ */
+ if (read_index_extension(istate, mmap, extoffsets[i]) < 0)
+ return -1;
+ }
+ }
free_directory_tree(root_directory);
istate->cache_nr = nr;
return 0;
--
1.8.4.2
next prev parent reply other threads:[~2013-11-27 12:02 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-27 12:00 [PATCH v4 00/24] Index-v5 Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 01/24] t2104: Don't fail for index versions other than [23] Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 02/24] read-cache: split index file version specific functionality Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 03/24] read-cache: move index v2 specific functions to their own file Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 04/24] read-cache: Re-read index if index file changed Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 05/24] add documentation for the index api Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 06/24] read-cache: add index reading api Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 07/24] make sure partially read index is not changed Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 08/24] grep.c: use index api Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 09/24] ls-files.c: " Thomas Gummerer
2013-11-30 9:17 ` Duy Nguyen
2013-11-30 10:30 ` Thomas Gummerer
2013-11-30 15:39 ` Antoine Pelisse
2013-11-30 20:08 ` Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 10/24] documentation: add documentation of the index-v5 file format Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 11/24] read-cache: make in-memory format aware of stat_crc Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 12/24] read-cache: read index-v5 Thomas Gummerer
2013-11-30 9:17 ` Duy Nguyen
2013-11-30 10:40 ` Thomas Gummerer
2013-11-30 12:19 ` Antoine Pelisse
2013-11-30 20:10 ` Thomas Gummerer
2013-11-30 15:26 ` Antoine Pelisse
2013-11-30 20:27 ` Thomas Gummerer
2013-11-27 12:00 ` Thomas Gummerer [this message]
2013-11-27 12:00 ` [PATCH v4 14/24] read-cache: read cache-tree in index-v5 Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 15/24] read-cache: write index-v5 Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 16/24] read-cache: write index-v5 cache-tree data Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 17/24] read-cache: write resolve-undo data for index-v5 Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 18/24] update-index.c: rewrite index when index-version is given Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 19/24] p0003-index.sh: add perf test for the index formats Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 20/24] introduce GIT_INDEX_VERSION environment variable Thomas Gummerer
2013-11-27 21:57 ` Eric Sunshine
2013-11-27 22:08 ` Junio C Hamano
2013-11-28 9:57 ` Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 21/24] test-lib: allow setting the index format version Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 22/24] t1600: add index v5 specific tests Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 23/24] POC for partial writing Thomas Gummerer
2013-11-30 9:58 ` Duy Nguyen
2013-11-30 10:50 ` Thomas Gummerer
2013-11-27 12:00 ` [PATCH v4 24/24] perf: add partial writing test Thomas Gummerer
2013-12-09 10:14 ` [PATCH v4 00/24] Index-v5 Thomas Gummerer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1385553659-9928-14-git-send-email-t.gummerer@gmail.com \
--to=t.gummerer@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=mhagger@alum.mit.edu \
--cc=pclouds@gmail.com \
--cc=ramsay@ramsay1.demon.co.uk \
--cc=robin.rosenberg@dewire.com \
--cc=sunshine@sunshineco.com \
--cc=tr@thomasrast.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.