36
#include "rebase-interactive.h"
37
#include "reset.h"
38
#include "branch.h"
39
+#include "log-tree.h"
40
41
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
42
194
struct object_id after;
195
};
196
197
+static struct update_ref_record *init_update_ref_record(const char *ref)
198
+{
199
+ struct update_ref_record *rec;
200
+
201
+ CALLOC_ARRAY(rec, 1);
202
+
203
+ oidcpy(&rec->before, null_oid());
204
+ oidcpy(&rec->after, null_oid());
205
+
206
+ /* This may fail, but that's fine, we will keep the null OID. */
207
+ read_ref(ref, &rec->before);
208
+
209
+ return rec;
210
+}
211
+
212
static int git_sequencer_config(const char *k, const char *v, void *cb)
213
{
214
struct replay_opts *opts = cb;
4122
return ret;
4123
}
4124
4109
-static int do_update_ref(struct repository *r, const char *ref_name)
4125
+static int write_update_refs_state(struct string_list *refs_to_oids)
4126
+{
4127
+ int result = 0;
4128
+ struct lock_file lock = LOCK_INIT;
4129
+ FILE *fp = NULL;
4130
+ struct string_list_item *item;
4131
+ char *path;
4132
+
4133
+ if (!refs_to_oids->nr)
4134
+ return 0;
4135
+
4136
+ path = rebase_path_update_refs(the_repository->gitdir);
4137
+
4138
+ if (safe_create_leading_directories(path)) {
4139
+ result = error(_("unable to create leading directories of %s"),
4140
+ path);
4141
+ goto cleanup;
4142
+ }
4143
+
4144
+ if (hold_lock_file_for_update(&lock, path, 0) < 0) {
4145
+ result = error(_("another 'rebase' process appears to be running; "
4146
+ "'%s.lock' already exists"),
4147
+ path);
4148
+ goto cleanup;
4149
+ }
4150
+
4151
+ fp = fdopen_lock_file(&lock, "w");
4152
+ if (!fp) {
4153
+ result = error_errno(_("could not open '%s' for writing"), path);
4154
+ rollback_lock_file(&lock);
4155
+ goto cleanup;
4156
+ }
4157
+
4158
+ for_each_string_list_item(item, refs_to_oids) {
4159
+ struct update_ref_record *rec = item->util;
4160
+ fprintf(fp, "%s\n%s\n%s\n", item->string,
4161
+ oid_to_hex(&rec->before), oid_to_hex(&rec->after));
4162
+ }
4163
+
4164
+ result = commit_lock_file(&lock);
4165
+
4166
+cleanup:
4167
+ free(path);
4168
+ return result;
4169
+}
4170
+
4171
+static int do_update_ref(struct repository *r, const char *refname)
4172
{
4173
+ struct string_list_item *item;
4174
+ struct string_list list = STRING_LIST_INIT_DUP;
4175
+
4176
+ if (sequencer_get_update_refs_state(r->gitdir, &list))
4177
+ return -1;
4178
+
4179
+ for_each_string_list_item(item, &list) {
4180
+ if (!strcmp(item->string, refname)) {
4181
+ struct update_ref_record *rec = item->util;
4182
+ if (read_ref("HEAD", &rec->after))
4183
+ return -1;
4184
+ break;
4185
+ }
4186
+ }
4187
+
4188
+ write_update_refs_state(&list);
4189
+ string_list_clear(&list, 1);
4190
return 0;
4191
}
4192
4193
+static int do_update_refs(struct repository *r)
4194
+{
4195
+ int res = 0;
4196
+ struct string_list_item *item;
4197
+ struct string_list refs_to_oids = STRING_LIST_INIT_DUP;
4198
+ struct ref_store *refs = get_main_ref_store(r);
4199
+
4200
+ if ((res = sequencer_get_update_refs_state(r->gitdir, &refs_to_oids)))
4201
+ return res;
4202
+
4203
+ for_each_string_list_item(item, &refs_to_oids) {
4204
+ struct update_ref_record *rec = item->util;
4205
+
4206
+ res |= refs_update_ref(refs, "rewritten during rebase",
4207
+ item->string,
4208
+ &rec->after, &rec->before,
4209
+ 0, UPDATE_REFS_MSG_ON_ERR);
4210
+ }
4211
+
4212
+ string_list_clear(&refs_to_oids, 1);
4213
+ return res;
4214
+}
4215
+
4216
static int is_final_fixup(struct todo_list *todo_list)
4217
{
4218
int i = todo_list->current;
4729
4730
strbuf_release(&buf);
4731
strbuf_release(&head_ref);
4732
+
4733
+ if (do_update_refs(r))
4734
+ return -1;
4735
}
4736
4737
/*
5816
5817
sti = string_list_insert(&ctx->refs_to_oids,
5818
decoration->name);
5714
- sti->util = oiddup(the_hash_algo->null_oid);
5819
+ sti->util = init_update_ref_record(decoration->name);
5820
}
5821
5822
item->offset_in_buf = base_offset;
5836
*/
5837
static int todo_list_add_update_ref_commands(struct todo_list *todo_list)
5838
{
5734
- int i;
5839
+ int i, res;
5840
static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP;
5841
static struct string_list decorate_refs_exclude_config = STRING_LIST_INIT_NODUP;
5842
static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP;
5872
}
5873
}
5874
5875
+ res = write_update_refs_state(&ctx.refs_to_oids);
5876
+
5877
string_list_clear(&ctx.refs_to_oids, 1);
5878
+
5879
+ if (res) {
5880
+ /* we failed, so clean up the new list. */
5881
+ free(ctx.items);
5882
+ return res;
5883
+ }
5884
+
5885
free(todo_list->items);
5886
todo_list->items = ctx.items;
5887
todo_list->nr = ctx.items_nr;