0b23b9bc75fdef20839fa9ecc36eac6dd6fdb1e4
1#include "cache.h"
2#include "tree-walk.h"
3
4static const char unresolve_usage[] =
5"git-unresolve <paths>...";
6
7static struct cache_file cache_file;
8static unsigned char head_sha1[20];
9static unsigned char merge_head_sha1[20];
10
11static struct cache_entry *read_one_ent(const char *which,
12 unsigned char *ent, const char *path,
13 int namelen, int stage)
14{
15 unsigned mode;
16 unsigned char sha1[20];
17 int size;
18 struct cache_entry *ce;
19
20 if (get_tree_entry(ent, path, sha1, &mode)) {
21 error("%s: not in %s branch.", path, which);
22 return NULL;
23 }
24 if (mode == S_IFDIR) {
25 error("%s: not a blob in %s branch.", path, which);
26 return NULL;
27 }
28 size = cache_entry_size(namelen);
29 ce = xcalloc(1, size);
30
31 memcpy(ce->sha1, sha1, 20);
32 memcpy(ce->name, path, namelen);
33 ce->ce_flags = create_ce_flags(namelen, stage);
34 ce->ce_mode = create_ce_mode(mode);
35 return ce;
36}
37
38static int unresolve_one(const char *path)
39{
40 int namelen = strlen(path);
41 int pos;
42 int ret = 0;
43 struct cache_entry *ce_2 = NULL, *ce_3 = NULL;
44
45 /* See if there is such entry in the index. */
46 pos = cache_name_pos(path, namelen);
47 if (pos < 0) {
48 /* If there isn't, either it is unmerged, or
49 * resolved as "removed" by mistake. We do not
50 * want to do anything in the former case.
51 */
52 pos = -pos-1;
53 if (pos < active_nr) {
54 struct cache_entry *ce = active_cache[pos];
55 if (ce_namelen(ce) == namelen &&
56 !memcmp(ce->name, path, namelen)) {
57 fprintf(stderr,
58 "%s: skipping still unmerged path.\n",
59 path);
60 goto free_return;
61 }
62 }
63 }
64
65 /* Grab blobs from given path from HEAD and MERGE_HEAD,
66 * stuff HEAD version in stage #2,
67 * stuff MERGE_HEAD version in stage #3.
68 */
69 ce_2 = read_one_ent("our", head_sha1, path, namelen, 2);
70 ce_3 = read_one_ent("their", merge_head_sha1, path, namelen, 3);
71
72 if (!ce_2 || !ce_3) {
73 ret = -1;
74 goto free_return;
75 }
76 if (!memcmp(ce_2->sha1, ce_3->sha1, 20) &&
77 ce_2->ce_mode == ce_3->ce_mode) {
78 fprintf(stderr, "%s: identical in both, skipping.\n",
79 path);
80 goto free_return;
81 }
82
83 remove_file_from_cache(path);
84 if (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {
85 error("%s: cannot add our version to the index.", path);
86 ret = -1;
87 goto free_return;
88 }
89 if (!add_cache_entry(ce_3, ADD_CACHE_OK_TO_ADD))
90 return 0;
91 error("%s: cannot add their version to the index.", path);
92 ret = -1;
93 free_return:
94 free(ce_2);
95 free(ce_3);
96 return ret;
97}
98
99static void read_head_pointers(void)
100{
101 if (read_ref(git_path("HEAD"), head_sha1))
102 die("Cannot read HEAD -- no initial commit yet?");
103 if (read_ref(git_path("MERGE_HEAD"), merge_head_sha1)) {
104 fprintf(stderr, "Not in the middle of a merge.\n");
105 exit(0);
106 }
107}
108
109int main(int ac, char **av)
110{
111 int i;
112 int err = 0;
113 int newfd;
114
115 if (ac < 2)
116 usage(unresolve_usage);
117
118 git_config(git_default_config);
119
120 /* Read HEAD and MERGE_HEAD; if MERGE_HEAD does not exist, we
121 * are not doing a merge, so exit with success status.
122 */
123 read_head_pointers();
124
125 /* Otherwise we would need to update the cache. */
126 newfd= hold_index_file_for_update(&cache_file, get_index_file());
127 if (newfd < 0)
128 die("unable to create new cachefile");
129
130 if (read_cache() < 0)
131 die("cache corrupted");
132
133 for (i = 1; i < ac; i++) {
134 char *arg = av[i];
135 err |= unresolve_one(arg);
136 }
137 if (err)
138 die("Error encountered; index not updated.");
139
140 if (active_cache_changed) {
141 if (write_cache(newfd, active_cache, active_nr) ||
142 commit_index_file(&cache_file))
143 die("Unable to write new cachefile");
144 }
145 return 0;
146}