THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
4.4KB

  1. #include "cache.h"
  2. #include "dir.h"
  3. #include "resolve-undo.h"
  4. #include "string-list.h"
  5. /* The only error case is to run out of memory in string-list */
  6. void record_resolve_undo(struct index_state *istate, struct cache_entry *ce)
  7. {
  8. struct string_list_item *lost;
  9. struct resolve_undo_info *ui;
  10. struct string_list *resolve_undo;
  11. int stage = ce_stage(ce);
  12. if (!stage)
  13. return;
  14. if (!istate->resolve_undo) {
  15. resolve_undo = xcalloc(1, sizeof(*resolve_undo));
  16. resolve_undo->strdup_strings = 1;
  17. istate->resolve_undo = resolve_undo;
  18. }
  19. resolve_undo = istate->resolve_undo;
  20. lost = string_list_insert(resolve_undo, ce->name);
  21. if (!lost->util)
  22. lost->util = xcalloc(1, sizeof(*ui));
  23. ui = lost->util;
  24. oidcpy(&ui->oid[stage - 1], &ce->oid);
  25. ui->mode[stage - 1] = ce->ce_mode;
  26. }
  27. void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
  28. {
  29. struct string_list_item *item;
  30. for_each_string_list_item(item, resolve_undo) {
  31. struct resolve_undo_info *ui = item->util;
  32. int i;
  33. if (!ui)
  34. continue;
  35. strbuf_addstr(sb, item->string);
  36. strbuf_addch(sb, 0);
  37. for (i = 0; i < 3; i++)
  38. strbuf_addf(sb, "%o%c", ui->mode[i], 0);
  39. for (i = 0; i < 3; i++) {
  40. if (!ui->mode[i])
  41. continue;
  42. strbuf_add(sb, ui->oid[i].hash, the_hash_algo->rawsz);
  43. }
  44. }
  45. }
  46. struct string_list *resolve_undo_read(const char *data, unsigned long size)
  47. {
  48. struct string_list *resolve_undo;
  49. size_t len;
  50. char *endptr;
  51. int i;
  52. const unsigned rawsz = the_hash_algo->rawsz;
  53. resolve_undo = xcalloc(1, sizeof(*resolve_undo));
  54. resolve_undo->strdup_strings = 1;
  55. while (size) {
  56. struct string_list_item *lost;
  57. struct resolve_undo_info *ui;
  58. len = strlen(data) + 1;
  59. if (size <= len)
  60. goto error;
  61. lost = string_list_insert(resolve_undo, data);
  62. if (!lost->util)
  63. lost->util = xcalloc(1, sizeof(*ui));
  64. ui = lost->util;
  65. size -= len;
  66. data += len;
  67. for (i = 0; i < 3; i++) {
  68. ui->mode[i] = strtoul(data, &endptr, 8);
  69. if (!endptr || endptr == data || *endptr)
  70. goto error;
  71. len = (endptr + 1) - (char*)data;
  72. if (size <= len)
  73. goto error;
  74. size -= len;
  75. data += len;
  76. }
  77. for (i = 0; i < 3; i++) {
  78. if (!ui->mode[i])
  79. continue;
  80. if (size < rawsz)
  81. goto error;
  82. oidread(&ui->oid[i], (const unsigned char *)data);
  83. size -= rawsz;
  84. data += rawsz;
  85. }
  86. }
  87. return resolve_undo;
  88. error:
  89. string_list_clear(resolve_undo, 1);
  90. error("Index records invalid resolve-undo information");
  91. return NULL;
  92. }
  93. void resolve_undo_clear_index(struct index_state *istate)
  94. {
  95. struct string_list *resolve_undo = istate->resolve_undo;
  96. if (!resolve_undo)
  97. return;
  98. string_list_clear(resolve_undo, 1);
  99. free(resolve_undo);
  100. istate->resolve_undo = NULL;
  101. istate->cache_changed |= RESOLVE_UNDO_CHANGED;
  102. }
  103. int unmerge_index_entry_at(struct index_state *istate, int pos)
  104. {
  105. const struct cache_entry *ce;
  106. struct string_list_item *item;
  107. struct resolve_undo_info *ru;
  108. int i, err = 0, matched;
  109. char *name;
  110. if (!istate->resolve_undo)
  111. return pos;
  112. ce = istate->cache[pos];
  113. if (ce_stage(ce)) {
  114. /* already unmerged */
  115. while ((pos < istate->cache_nr) &&
  116. ! strcmp(istate->cache[pos]->name, ce->name))
  117. pos++;
  118. return pos - 1; /* return the last entry processed */
  119. }
  120. item = string_list_lookup(istate->resolve_undo, ce->name);
  121. if (!item)
  122. return pos;
  123. ru = item->util;
  124. if (!ru)
  125. return pos;
  126. matched = ce->ce_flags & CE_MATCHED;
  127. name = xstrdup(ce->name);
  128. remove_index_entry_at(istate, pos);
  129. for (i = 0; i < 3; i++) {
  130. struct cache_entry *nce;
  131. if (!ru->mode[i])
  132. continue;
  133. nce = make_cache_entry(istate,
  134. ru->mode[i],
  135. &ru->oid[i],
  136. name, i + 1, 0);
  137. if (matched)
  138. nce->ce_flags |= CE_MATCHED;
  139. if (add_index_entry(istate, nce, ADD_CACHE_OK_TO_ADD)) {
  140. err = 1;
  141. error("cannot unmerge '%s'", name);
  142. }
  143. }
  144. free(name);
  145. if (err)
  146. return pos;
  147. free(ru);
  148. item->util = NULL;
  149. return unmerge_index_entry_at(istate, pos);
  150. }
  151. void unmerge_marked_index(struct index_state *istate)
  152. {
  153. int i;
  154. if (!istate->resolve_undo)
  155. return;
  156. for (i = 0; i < istate->cache_nr; i++) {
  157. const struct cache_entry *ce = istate->cache[i];
  158. if (ce->ce_flags & CE_MATCHED)
  159. i = unmerge_index_entry_at(istate, i);
  160. }
  161. }
  162. void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
  163. {
  164. int i;
  165. if (!istate->resolve_undo)
  166. return;
  167. for (i = 0; i < istate->cache_nr; i++) {
  168. const struct cache_entry *ce = istate->cache[i];
  169. if (!ce_path_match(istate, ce, pathspec, NULL))
  170. continue;
  171. i = unmerge_index_entry_at(istate, i);
  172. }
  173. }