From: Junio C Hamano Date: Mon, 6 Nov 2017 04:11:21 +0000 (+0900) Subject: Merge branch 'ma/lockfile-fixes' X-Git-Tag: v2.16.0-rc0~183 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0b646bcac96a57e345887e607e0b8c9a64ff262a;p=thirdparty%2Fgit.git Merge branch 'ma/lockfile-fixes' An earlier update made it possible to use an on-stack in-core lockfile structure (as opposed to having to deliberately leak an on-heap one). Many codepaths have been updated to take advantage of this new facility. * ma/lockfile-fixes: read_cache: roll back lock in `update_index_if_able()` read-cache: leave lock in right state in `write_locked_index()` read-cache: drop explicit `CLOSE_LOCK`-flag cache.h: document `write_locked_index()` apply: remove `newfd` from `struct apply_state` apply: move lockfile into `apply_state` cache-tree: simplify locking logic checkout-index: simplify locking logic tempfile: fix documentation on `delete_tempfile()` lockfile: fix documentation on `close_lock_file_gently()` treewide: prefer lockfiles on the stack sha1_file: do not leak `lock_file` --- 0b646bcac96a57e345887e607e0b8c9a64ff262a diff --cc config.c index adb7d7a3e5,0e61e863d6..903abf9533 --- a/config.c +++ b/config.c @@@ -2801,24 -2795,7 +2800,24 @@@ static int git_config_copy_or_rename_se ; /* do nothing */ if (buf[i] == '[') { /* it's a section */ - int offset = section_name_match(&buf[i], old_name); + int offset; + is_section = 1; + + /* + * When encountering a new section under -c we + * need to flush out any section we're already + * coping and begin anew. There might be + * multiple [branch "$name"] sections. + */ + if (copystr.len > 0) { + if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) { - ret = write_error(get_lock_file_path(lock)); ++ ret = write_error(get_lock_file_path(&lock)); + goto out; + } + strbuf_reset(©str); + } + + offset = section_name_match(&buf[i], old_name); if (offset > 0) { ret++; if (new_name == NULL) { @@@ -2826,29 -2803,25 +2825,29 @@@ continue; } store.baselen = strlen(new_name); - if (write_section(out_fd, new_name) < 0) { - ret = write_error(get_lock_file_path(&lock)); - goto out; - } - /* - * We wrote out the new section, with - * a newline, now skip the old - * section's length - */ - output += offset + i; - if (strlen(output) > 0) { + if (!copy) { + if (write_section(out_fd, new_name) < 0) { - ret = write_error(get_lock_file_path(lock)); ++ ret = write_error(get_lock_file_path(&lock)); + goto out; + } /* - * More content means there's - * a declaration to put on the - * next line; indent with a - * tab + * We wrote out the new section, with + * a newline, now skip the old + * section's length */ - output -= 1; - output[0] = '\t'; + output += offset + i; + if (strlen(output) > 0) { + /* + * More content means there's + * a declaration to put on the + * next line; indent with a + * tab + */ + output -= 1; + output[0] = '\t'; + } + } else { + copystr = store_create_section(new_name); } } remove = 0; @@@ -2856,30 -2829,11 +2855,30 @@@ if (remove) continue; length = strlen(output); + + if (!is_section && copystr.len > 0) { + strbuf_add(©str, output, length); + } + if (write_in_full(out_fd, output, length) < 0) { - ret = write_error(get_lock_file_path(lock)); + ret = write_error(get_lock_file_path(&lock)); goto out; } } + + /* + * Copy a trailing section at the end of the config, won't be + * flushed by the usual "flush because we have a new section + * logic in the loop above. + */ + if (copystr.len > 0) { + if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) { - ret = write_error(get_lock_file_path(lock)); ++ ret = write_error(get_lock_file_path(&lock)); + goto out; + } + strbuf_reset(©str); + } + fclose(config_file); config_file = NULL; commit_and_out: