git

Форк
0
/
resolve-undo.c 
178 строк · 4.2 Кб
1
#define USE_THE_REPOSITORY_VARIABLE
2

3
#include "git-compat-util.h"
4
#include "dir.h"
5
#include "hash.h"
6
#include "read-cache.h"
7
#include "resolve-undo.h"
8
#include "sparse-index.h"
9
#include "string-list.h"
10

11
/* The only error case is to run out of memory in string-list */
12
void record_resolve_undo(struct index_state *istate, struct cache_entry *ce)
13
{
14
	struct string_list_item *lost;
15
	struct resolve_undo_info *ui;
16
	struct string_list *resolve_undo;
17
	int stage = ce_stage(ce);
18

19
	if (!stage)
20
		return;
21

22
	if (!istate->resolve_undo) {
23
		CALLOC_ARRAY(resolve_undo, 1);
24
		resolve_undo->strdup_strings = 1;
25
		istate->resolve_undo = resolve_undo;
26
	}
27
	resolve_undo = istate->resolve_undo;
28
	lost = string_list_insert(resolve_undo, ce->name);
29
	if (!lost->util)
30
		lost->util = xcalloc(1, sizeof(*ui));
31
	ui = lost->util;
32
	oidcpy(&ui->oid[stage - 1], &ce->oid);
33
	ui->mode[stage - 1] = ce->ce_mode;
34
}
35

36
void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
37
{
38
	struct string_list_item *item;
39
	for_each_string_list_item(item, resolve_undo) {
40
		struct resolve_undo_info *ui = item->util;
41
		int i;
42

43
		if (!ui)
44
			continue;
45
		strbuf_addstr(sb, item->string);
46
		strbuf_addch(sb, 0);
47
		for (i = 0; i < 3; i++)
48
			strbuf_addf(sb, "%o%c", ui->mode[i], 0);
49
		for (i = 0; i < 3; i++) {
50
			if (!ui->mode[i])
51
				continue;
52
			strbuf_add(sb, ui->oid[i].hash, the_hash_algo->rawsz);
53
		}
54
	}
55
}
56

57
struct string_list *resolve_undo_read(const char *data, unsigned long size)
58
{
59
	struct string_list *resolve_undo;
60
	size_t len;
61
	char *endptr;
62
	int i;
63
	const unsigned rawsz = the_hash_algo->rawsz;
64

65
	CALLOC_ARRAY(resolve_undo, 1);
66
	resolve_undo->strdup_strings = 1;
67

68
	while (size) {
69
		struct string_list_item *lost;
70
		struct resolve_undo_info *ui;
71

72
		len = strlen(data) + 1;
73
		if (size <= len)
74
			goto error;
75
		lost = string_list_insert(resolve_undo, data);
76
		if (!lost->util)
77
			lost->util = xcalloc(1, sizeof(*ui));
78
		ui = lost->util;
79
		size -= len;
80
		data += len;
81

82
		for (i = 0; i < 3; i++) {
83
			ui->mode[i] = strtoul(data, &endptr, 8);
84
			if (!endptr || endptr == data || *endptr)
85
				goto error;
86
			len = (endptr + 1) - (char*)data;
87
			if (size <= len)
88
				goto error;
89
			size -= len;
90
			data += len;
91
		}
92

93
		for (i = 0; i < 3; i++) {
94
			if (!ui->mode[i])
95
				continue;
96
			if (size < rawsz)
97
				goto error;
98
			oidread(&ui->oid[i], (const unsigned char *)data,
99
				the_repository->hash_algo);
100
			size -= rawsz;
101
			data += rawsz;
102
		}
103
	}
104
	return resolve_undo;
105

106
error:
107
	string_list_clear(resolve_undo, 1);
108
	error("Index records invalid resolve-undo information");
109
	return NULL;
110
}
111

112
void resolve_undo_clear_index(struct index_state *istate)
113
{
114
	struct string_list *resolve_undo = istate->resolve_undo;
115
	if (!resolve_undo)
116
		return;
117
	string_list_clear(resolve_undo, 1);
118
	free(resolve_undo);
119
	istate->resolve_undo = NULL;
120
	istate->cache_changed |= RESOLVE_UNDO_CHANGED;
121
}
122

123
int unmerge_index_entry(struct index_state *istate, const char *path,
124
			struct resolve_undo_info *ru, unsigned ce_flags)
125
{
126
	int i = index_name_pos(istate, path, strlen(path));
127

128
	if (i < 0) {
129
		/* unmerged? */
130
		i = -i - 1;
131
		if (i < istate->cache_nr &&
132
		    !strcmp(istate->cache[i]->name, path))
133
			/* yes, it is already unmerged */
134
			return 0;
135
		/* fallthru: resolved to removal */
136
	} else {
137
		/* merged - remove it to replace it with unmerged entries */
138
		remove_index_entry_at(istate, i);
139
	}
140

141
	for (i = 0; i < 3; i++) {
142
		struct cache_entry *ce;
143
		if (!ru->mode[i])
144
			continue;
145
		ce = make_cache_entry(istate, ru->mode[i], &ru->oid[i],
146
				      path, i + 1, 0);
147
		ce->ce_flags |= ce_flags;
148
		if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD))
149
			return error("cannot unmerge '%s'", path);
150
	}
151
	return 0;
152
}
153

154
void unmerge_index(struct index_state *istate, const struct pathspec *pathspec,
155
		   unsigned ce_flags)
156
{
157
	struct string_list_item *item;
158

159
	if (!istate->resolve_undo)
160
		return;
161

162
	/* TODO: audit for interaction with sparse-index. */
163
	ensure_full_index(istate);
164

165
	for_each_string_list_item(item, istate->resolve_undo) {
166
		const char *path = item->string;
167
		struct resolve_undo_info *ru = item->util;
168
		if (!item->util)
169
			continue;
170
		if (!match_pathspec(istate, pathspec,
171
				    item->string, strlen(item->string),
172
				    0, NULL, 0))
173
			continue;
174
		unmerge_index_entry(istate, path, ru, ce_flags);
175
		free(ru);
176
		item->util = NULL;
177
	}
178
}
179

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.