diff options
72 files changed, 632 insertions, 1352 deletions
diff --git a/Documentation/RelNotes/2.51.0.adoc b/Documentation/RelNotes/2.51.0.adoc index a89d459d2e..f8adc2c5cf 100644 --- a/Documentation/RelNotes/2.51.0.adoc +++ b/Documentation/RelNotes/2.51.0.adoc @@ -67,6 +67,11 @@ UI, Workflows & Features * "git switch" and "git restore" are declared to be no longer experimental. + * "git -c alias.foo=bar foo -h baz" reported "'foo' is aliased to + 'bar'" and then went on to run "git foo -h baz", which was + unexpected. Tighten the rule so that alias expansion is reported + only when "-h" is the sole option. + Performance, Internal Implementation, Development Support etc. -------------------------------------------------------------- @@ -136,6 +141,9 @@ Performance, Internal Implementation, Development Support etc. support a single object source that belongs to one repository. A midx does span mulitple "object sources". + * Reduce implicit assumption and dependence on the_repository in the + object-file subsystem. + Fixes since v2.50 ----------------- @@ -284,6 +292,11 @@ including security updates, are included in this release. and also they learn to honor the -U<n> command-line option. (merge 2b3ae04011 lm/add-p-context later to maint). + * The case where a new submodule takes a path where used to be a + completely different subproject is now dealt a bit better than + before. + (merge 5ed8c5b465 kj/renamed-submodule later to maint). + * Other code cleanup, docfix, build fix, etc. (merge b257adb571 lo/my-first-ow-doc-update later to maint). (merge 8b34b6a220 ly/sequencer-update-squash-is-fixup-only later to maint). diff --git a/Documentation/git-submodule.adoc b/Documentation/git-submodule.adoc index 87d8e0f0c5..503c84a200 100644 --- a/Documentation/git-submodule.adoc +++ b/Documentation/git-submodule.adoc @@ -307,6 +307,13 @@ OPTIONS --force:: This option is only valid for add, deinit and update commands. When running add, allow adding an otherwise ignored submodule path. + This option is also used to bypass a check that the submodule's name + is not already in use. By default, 'git submodule add' will fail if + the proposed name (which is derived from the path) is already registered + for another submodule in the repository. Using '--force' allows the command + to proceed by automatically generating a unique name by appending a number + to the conflicting name (e.g., if a submodule named 'child' exists, it will + try 'child1', and so on). When running deinit the submodule working trees will be removed even if they contain local changes. When running update (only effective with the checkout procedure), @@ -3621,7 +3621,7 @@ static int try_threeway(struct apply_state *state, /* Preimage the patch was prepared for */ if (patch->is_new) - write_object_file("", 0, OBJ_BLOB, &pre_oid); + odb_write_object(the_repository->objects, "", 0, OBJ_BLOB, &pre_oid); else if (repo_get_oid(the_repository, patch->old_oid_prefix, &pre_oid) || read_blob_object(&buf, &pre_oid, patch->old_mode)) return error(_("repository lacks the necessary blob to perform 3-way merge.")); @@ -3637,7 +3637,8 @@ static int try_threeway(struct apply_state *state, return -1; } /* post_oid is theirs */ - write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &post_oid); + odb_write_object(the_repository->objects, tmp_image.buf.buf, + tmp_image.buf.len, OBJ_BLOB, &post_oid); image_clear(&tmp_image); /* our_oid is ours */ @@ -3650,7 +3651,8 @@ static int try_threeway(struct apply_state *state, return error(_("cannot read the current contents of '%s'"), patch->old_name); } - write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &our_oid); + odb_write_object(the_repository->objects, tmp_image.buf.buf, + tmp_image.buf.len, OBJ_BLOB, &our_oid); image_clear(&tmp_image); /* in-core three-way merge between post and our using pre as base */ @@ -4360,7 +4362,8 @@ static int add_index_file(struct apply_state *state, } fill_stat_cache_info(state->repo->index, ce, &st); } - if (write_object_file(buf, size, OBJ_BLOB, &ce->oid) < 0) { + if (odb_write_object(the_repository->objects, buf, size, + OBJ_BLOB, &ce->oid) < 0) { discard_cache_entry(ce); return error(_("unable to create backing store " "for newly created file %s"), path); diff --git a/builtin/cat-file.c b/builtin/cat-file.c index b9eb2bb3b9..fce0b06451 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -848,7 +848,7 @@ static void batch_each_object(struct batch_options *opt, }; struct bitmap_index *bitmap = prepare_bitmap_git(the_repository); - for_each_loose_object(batch_one_object_loose, &payload, 0); + for_each_loose_object(the_repository->objects, batch_one_object_loose, &payload, 0); if (bitmap && !for_each_bitmapped_object(bitmap, &opt->objects_filter, batch_one_object_bitmapped, &payload)) { diff --git a/builtin/checkout.c b/builtin/checkout.c index 3c196c150a..f9453473fe 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -327,7 +327,7 @@ static int checkout_merged(int pos, const struct checkout *state, * (it also writes the merge result to the object database even * when it may contain conflicts). */ - if (write_object_file(result_buf.ptr, result_buf.size, OBJ_BLOB, &oid)) + if (odb_write_object(the_repository->objects, result_buf.ptr, result_buf.size, OBJ_BLOB, &oid)) die(_("Unable to add merge result for '%s'"), path); free(result_buf.ptr); ce = make_transient_cache_entry(mode, &oid, path, 2, ce_mem_pool); diff --git a/builtin/count-objects.c b/builtin/count-objects.c index b1148a68fa..a61d3b46aa 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -118,7 +118,7 @@ int cmd_count_objects(int argc, report_linked_checkout_garbage(the_repository); } - for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), + for_each_loose_file_in_source(the_repository->objects->sources, count_loose, count_cruft, NULL, NULL); if (verbose) { diff --git a/builtin/fast-import.c b/builtin/fast-import.c index adf3994be1..2c35f9345d 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -822,11 +822,11 @@ static char *keep_pack(const char *curr_index_name) die_errno("failed to write keep file"); odb_pack_name(pack_data->repo, &name, pack_data->hash, "pack"); - if (finalize_object_file(pack_data->pack_name, name.buf)) + if (finalize_object_file(pack_data->repo, pack_data->pack_name, name.buf)) die("cannot store pack file"); odb_pack_name(pack_data->repo, &name, pack_data->hash, "idx"); - if (finalize_object_file(curr_index_name, name.buf)) + if (finalize_object_file(pack_data->repo, curr_index_name, name.buf)) die("cannot store index file"); free((void *)curr_index_name); return strbuf_detach(&name, NULL); diff --git a/builtin/fsck.c b/builtin/fsck.c index 0ec6ca06e3..543a2cdb5c 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -393,7 +393,8 @@ static void check_connectivity(void) * and ignore any that weren't present in our earlier * traversal. */ - for_each_loose_object(mark_loose_unreachable_referents, NULL, 0); + for_each_loose_object(the_repository->objects, + mark_loose_unreachable_referents, NULL, 0); for_each_packed_object(the_repository, mark_packed_unreachable_referents, NULL, @@ -632,7 +633,7 @@ static int fsck_loose(const struct object_id *oid, const char *path, oi.sizep = &size; oi.typep = &type; - if (read_loose_object(path, oid, &real_oid, &contents, &oi) < 0) { + if (read_loose_object(the_repository, path, oid, &real_oid, &contents, &oi) < 0) { if (contents && !oideq(&real_oid, oid)) err = error(_("%s: hash-path mismatch, found at: %s"), oid_to_hex(&real_oid), path); @@ -687,7 +688,7 @@ static int fsck_subdir(unsigned int nr, const char *path UNUSED, void *data) return 0; } -static void fsck_object_dir(const char *path) +static void fsck_source(struct odb_source *source) { struct progress *progress = NULL; struct for_each_loose_cb cb_data = { @@ -701,8 +702,8 @@ static void fsck_object_dir(const char *path) progress = start_progress(the_repository, _("Checking object directories"), 256); - for_each_loose_file_in_objdir(path, fsck_loose, fsck_cruft, fsck_subdir, - &cb_data); + for_each_loose_file_in_source(source, fsck_loose, + fsck_cruft, fsck_subdir, &cb_data); display_progress(progress, 256); stop_progress(&progress); } @@ -994,13 +995,14 @@ int cmd_fsck(int argc, fsck_refs(the_repository); if (connectivity_only) { - for_each_loose_object(mark_loose_for_connectivity, NULL, 0); + for_each_loose_object(the_repository->objects, + mark_loose_for_connectivity, NULL, 0); for_each_packed_object(the_repository, mark_packed_for_connectivity, NULL, 0); } else { odb_prepare_alternates(the_repository->objects); for (source = the_repository->objects->sources; source; source = source->next) - fsck_object_dir(source->path); + fsck_source(source); if (check_full) { struct packed_git *p; diff --git a/builtin/gc.c b/builtin/gc.c index 6fd4dc26be..0edd94a76f 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1309,7 +1309,7 @@ static int loose_object_auto_condition(struct gc_config *cfg UNUSED) if (loose_object_auto_limit < 0) return 1; - return for_each_loose_file_in_objdir(the_repository->objects->sources->path, + return for_each_loose_file_in_source(the_repository->objects->sources, loose_object_count, NULL, NULL, &count); } @@ -1344,7 +1344,7 @@ static int pack_loose(struct maintenance_run_opts *opts) * Do not start pack-objects process * if there are no loose objects. */ - if (!for_each_loose_file_in_objdir(r->objects->sources->path, + if (!for_each_loose_file_in_source(r->objects->sources, bail_on_loose, NULL, NULL, NULL)) return 0; @@ -1384,11 +1384,9 @@ static int pack_loose(struct maintenance_run_opts *opts) else if (data.batch_size > 0) data.batch_size--; /* Decrease for equality on limit. */ - for_each_loose_file_in_objdir(r->objects->sources->path, + for_each_loose_file_in_source(r->objects->sources, write_loose_object_to_stdin, - NULL, - NULL, - &data); + NULL, NULL, &data); fclose(data.in); diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 53f1a7cd71..f91c301bba 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1598,7 +1598,7 @@ static void rename_tmp_packfile(const char **final_name, if (!*final_name || strcmp(*final_name, curr_name)) { if (!*final_name) *final_name = odb_pack_name(the_repository, name, hash, ext); - if (finalize_object_file(curr_name, *final_name)) + if (finalize_object_file(the_repository, curr_name, *final_name)) die(_("unable to rename temporary '*.%s' file to '%s'"), ext, *final_name); } else if (make_read_only_if_same) { diff --git a/builtin/merge-file.c b/builtin/merge-file.c index 3da4ca2c8c..46775d0c79 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -155,7 +155,8 @@ int cmd_merge_file(int argc, if (object_id && !to_stdout) { struct object_id oid; if (result.size) { - if (write_object_file(result.ptr, result.size, OBJ_BLOB, &oid) < 0) + if (odb_write_object(the_repository->objects, result.ptr, + result.size, OBJ_BLOB, &oid) < 0) ret = error(_("Could not write object file")); } else { oidcpy(&oid, the_hash_algo->empty_blob); diff --git a/builtin/mktag.c b/builtin/mktag.c index e078c97d03..7cf6e1230a 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -106,7 +106,7 @@ int cmd_mktag(int argc, if (verify_object_in_tag(&tagged_oid, &tagged_type) < 0) die(_("tag on stdin did not refer to a valid object")); - if (write_object_file(buf.buf, buf.len, OBJ_TAG, &result) < 0) + if (odb_write_object(the_repository->objects, buf.buf, buf.len, OBJ_TAG, &result) < 0) die(_("unable to write tag file")); strbuf_release(&buf); diff --git a/builtin/mktree.c b/builtin/mktree.c index 81df7f6099..12772303f5 100644 --- a/builtin/mktree.c +++ b/builtin/mktree.c @@ -63,7 +63,7 @@ static void write_tree(struct object_id *oid) strbuf_add(&buf, ent->oid.hash, the_hash_algo->rawsz); } - write_object_file(buf.buf, buf.len, OBJ_TREE, oid); + odb_write_object(the_repository->objects, buf.buf, buf.len, OBJ_TREE, oid); strbuf_release(&buf); } diff --git a/builtin/notes.c b/builtin/notes.c index d2252cf534..6fb4144da3 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -229,7 +229,8 @@ static void prepare_note_data(const struct object_id *object, struct note_data * static void write_note_data(struct note_data *d, struct object_id *oid) { - if (write_object_file(d->buf.buf, d->buf.len, OBJ_BLOB, oid)) { + if (odb_write_object(the_repository->objects, d->buf.buf, + d->buf.len, OBJ_BLOB, oid)) { int status = die_message(_("unable to write note object")); if (d->edit_path) diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 1f084a1b8d..53a2256250 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1455,7 +1455,7 @@ static void write_pack_file(void) strbuf_setlen(&tmpname, tmpname_len); } - rename_tmp_packfile_idx(&tmpname, &idx_tmp_name); + rename_tmp_packfile_idx(the_repository, &tmpname, &idx_tmp_name); free(idx_tmp_name); strbuf_release(&tmpname); @@ -1709,8 +1709,16 @@ static int want_object_in_pack_mtime(const struct object_id *oid, struct odb_source *source; struct list_head *pos; - if (!exclude && local && has_loose_object_nonlocal(oid)) - return 0; + if (!exclude && local) { + /* + * Note that we start iterating at `sources->next` so that we + * skip the local object source. + */ + struct odb_source *source = the_repository->objects->sources->next; + for (; source; source = source->next) + if (has_loose_object(source, oid)) + return 0; + } /* * If we already know the pack object lives in, start checks from that @@ -3966,7 +3974,14 @@ static void add_cruft_object_entry(const struct object_id *oid, enum object_type } else { if (!want_object_in_pack_mtime(oid, 0, &pack, &offset, mtime)) return; - if (!pack && type == OBJ_BLOB && !has_loose_object(oid)) { + if (!pack && type == OBJ_BLOB) { + struct odb_source *source = the_repository->objects->sources; + int found = 0; + + for (; !found && source; source = source->next) + if (has_loose_object(source, oid)) + found = 1; + /* * If a traversed tree has a missing blob then we want * to avoid adding that missing object to our pack. @@ -3980,7 +3995,8 @@ static void add_cruft_object_entry(const struct object_id *oid, enum object_type * limited to "ensure non-tip blobs which don't exist in * packs do exist via loose objects". Confused? */ - return; + if (!found) + return; } entry = create_object_entry(oid, type, pack_name_hash_fn(name), @@ -4368,7 +4384,7 @@ static int add_loose_object(const struct object_id *oid, const char *path, */ static void add_unreachable_loose_objects(struct rev_info *revs) { - for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), + for_each_loose_file_in_source(the_repository->objects->sources, add_loose_object, NULL, NULL, revs); } @@ -4437,7 +4453,8 @@ static void loosen_unused_packed_objects(void) if (!packlist_find(&to_pack, &oid) && !has_sha1_pack_kept_or_nonlocal(&oid) && !loosened_object_can_be_discarded(&oid, p->mtime)) { - if (force_object_loose(&oid, p->mtime)) + if (force_object_loose(the_repository->objects->sources, + &oid, p->mtime)) die(_("unable to force loose object")); loosened_objects_nr++; } diff --git a/builtin/prune.c b/builtin/prune.c index d1c0ee1419..55635a891f 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -198,7 +198,7 @@ int cmd_prune(int argc, revs.exclude_promisor_objects = 1; } - for_each_loose_file_in_objdir(repo_get_object_directory(repo), + for_each_loose_file_in_source(repo->objects->sources, prune_object, prune_cruft, prune_subdir, &revs); prune_packed_objects(show_only ? PRUNE_PACKED_DRY_RUN : 0); diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 82d516a42c..1113137a6f 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -760,8 +760,8 @@ static void prepare_push_cert_sha1(struct child_process *proc) int bogs /* beginning_of_gpg_sig */; already_done = 1; - if (write_object_file(push_cert.buf, push_cert.len, OBJ_BLOB, - &push_cert_oid)) + if (odb_write_object(the_repository->objects, push_cert.buf, + push_cert.len, OBJ_BLOB, &push_cert_oid)) oidclr(&push_cert_oid, the_repository->hash_algo); memset(&sigcheck, '\0', sizeof(sigcheck)); diff --git a/builtin/replace.c b/builtin/replace.c index 19897ef927..900b560a77 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -489,7 +489,8 @@ static int create_graft(int argc, const char **argv, int force, int gentle) return -1; } - if (write_object_file(buf.buf, buf.len, OBJ_COMMIT, &new_oid)) { + if (odb_write_object(the_repository->objects, buf.buf, + buf.len, OBJ_COMMIT, &new_oid)) { strbuf_release(&buf); return error(_("could not write replacement commit for: '%s'"), old_ref); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 28f34f7bc1..07a1935cbe 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -32,6 +32,8 @@ #include "advice.h" #include "branch.h" #include "list-objects-filter-options.h" +#include "wildmatch.h" +#include "strbuf.h" #define OPT_QUIET (1 << 0) #define OPT_CACHED (1 << 1) @@ -3307,6 +3309,8 @@ static void configure_added_submodule(struct add_data *add_data) char *key; struct child_process add_submod = CHILD_PROCESS_INIT; struct child_process add_gitmodules = CHILD_PROCESS_INIT; + const struct string_list *values; + int matched = 0; key = xstrfmt("submodule.%s.url", add_data->sm_name); repo_config_set_gently(the_repository, key, add_data->realrepo); @@ -3349,20 +3353,28 @@ static void configure_added_submodule(struct add_data *add_data) * is_submodule_active(), since that function needs to find * out the value of "submodule.active" again anyway. */ - if (!repo_config_get(the_repository, "submodule.active")) { + if (repo_config_get(the_repository, "submodule.active") || /* key absent */ + repo_config_get_string_multi(the_repository, "submodule.active", &values)) { /* * If the submodule being added isn't already covered by the * current configured pathspec, set the submodule's active flag */ - if (!is_submodule_active(the_repository, add_data->sm_path)) { + key = xstrfmt("submodule.%s.active", add_data->sm_name); + repo_config_set_gently(the_repository, key, "true"); + free(key); + } else { + for (size_t i = 0; i < values->nr; i++) { + const char *pat = values->items[i].string; + if (!wildmatch(pat, add_data->sm_path, 0)) { /* match found */ + matched = 1; + break; + } + } + if (!matched) { /* no pattern matched -> force-enable */ key = xstrfmt("submodule.%s.active", add_data->sm_name); repo_config_set_gently(the_repository, key, "true"); free(key); } - } else { - key = xstrfmt("submodule.%s.active", add_data->sm_name); - repo_config_set_gently(the_repository, key, "true"); - free(key); } } @@ -3423,6 +3435,9 @@ static int module_add(int argc, const char **argv, const char *prefix, struct add_data add_data = ADD_DATA_INIT; const char *ref_storage_format = NULL; char *to_free = NULL; + const struct submodule *existing; + struct strbuf buf = STRBUF_INIT; + char *sm_name_to_free = NULL; struct option options[] = { OPT_STRING('b', "branch", &add_data.branch, N_("branch"), N_("branch of repository to add as submodule")), @@ -3525,6 +3540,28 @@ static int module_add(int argc, const char **argv, const char *prefix, if(!add_data.sm_name) add_data.sm_name = add_data.sm_path; + existing = submodule_from_name(the_repository, + null_oid(the_hash_algo), + add_data.sm_name); + + if (existing && strcmp(existing->path, add_data.sm_path)) { + if (!force) { + die(_("submodule name '%s' already used for path '%s'"), + add_data.sm_name, existing->path); + } + /* --force: build <name><n> until unique */ + for (int i = 1; ; i++) { + strbuf_reset(&buf); + strbuf_addf(&buf, "%s%d", add_data.sm_name, i); + if (!submodule_from_name(the_repository, + null_oid(the_hash_algo), + buf.buf)) { + break; + } + } + add_data.sm_name = sm_name_to_free = strbuf_detach(&buf, NULL); + } + if (check_submodule_name(add_data.sm_name)) die(_("'%s' is not a valid submodule name"), add_data.sm_name); @@ -3540,6 +3577,7 @@ static int module_add(int argc, const char **argv, const char *prefix, ret = 0; cleanup: + free(sm_name_to_free); free(add_data.sm_path); free(to_free); strbuf_release(&sb); diff --git a/builtin/tag.c b/builtin/tag.c index 25f30e3f9b..f0665af3ac 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -271,8 +271,8 @@ static int build_tag_object(struct strbuf *buf, int sign, struct object_id *resu struct object_id *compat_oid = NULL, compat_oid_buf; if (sign && do_sign(buf, &compat_oid, &compat_oid_buf) < 0) return error(_("unable to sign the tag")); - if (write_object_file_flags(buf->buf, buf->len, OBJ_TAG, result, - compat_oid, 0) < 0) + if (odb_write_object_ext(the_repository->objects, buf->buf, + buf->len, OBJ_TAG, result, compat_oid, 0) < 0) return error(_("unable to write tag file")); return 0; } diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 26aa885da9..7ae7c82b6c 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -204,8 +204,8 @@ static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf) { struct object_id oid; - if (write_object_file(obj_buf->buffer, obj_buf->size, - obj->type, &oid) < 0) + if (odb_write_object(the_repository->objects, obj_buf->buffer, obj_buf->size, + obj->type, &oid) < 0) die("failed to write object %s", oid_to_hex(&obj->oid)); obj->flags |= FLAG_WRITTEN; } @@ -272,16 +272,16 @@ static void write_object(unsigned nr, enum object_type type, void *buf, unsigned long size) { if (!strict) { - if (write_object_file(buf, size, type, - &obj_list[nr].oid) < 0) + if (odb_write_object(the_repository->objects, buf, size, type, + &obj_list[nr].oid) < 0) die("failed to write object"); added_object(nr, type, buf, size); free(buf); obj_list[nr].obj = NULL; } else if (type == OBJ_BLOB) { struct blob *blob; - if (write_object_file(buf, size, type, - &obj_list[nr].oid) < 0) + if (odb_write_object(the_repository->objects, buf, size, type, + &obj_list[nr].oid) < 0) die("failed to write object"); added_object(nr, type, buf, size); free(buf); @@ -403,7 +403,8 @@ static void stream_blob(unsigned long size, unsigned nr) data.zstream = &zstream; git_inflate_init(&zstream); - if (stream_loose_object(&in_stream, size, &info->oid)) + if (stream_loose_object(the_repository->objects->sources, + &in_stream, size, &info->oid)) die(_("failed to write object in stream")); if (data.status != Z_STREAM_END) diff --git a/bulk-checkin.c b/bulk-checkin.c index 16df86c0ba..b2809ab039 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -46,7 +46,7 @@ static void finish_tmp_packfile(struct strbuf *basename, stage_tmp_packfiles(the_repository, basename, pack_tmp_name, written_list, nr_written, NULL, pack_idx_opts, hash, &idx_tmp_name); - rename_tmp_packfile_idx(basename, &idx_tmp_name); + rename_tmp_packfile_idx(the_repository, basename, &idx_tmp_name); free(idx_tmp_name); } diff --git a/cache-tree.c b/cache-tree.c index a4bc14ad15..66ef2becbe 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -456,9 +456,8 @@ static int update_one(struct cache_tree *it, } else if (dryrun) { hash_object_file(the_hash_algo, buffer.buf, buffer.len, OBJ_TREE, &it->oid); - } else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE, - &it->oid, NULL, flags & WRITE_TREE_SILENT - ? WRITE_OBJECT_FILE_SILENT : 0)) { + } else if (odb_write_object_ext(the_repository->objects, buffer.buf, buffer.len, OBJ_TREE, + &it->oid, NULL, flags & WRITE_TREE_SILENT ? WRITE_OBJECT_SILENT : 0)) { strbuf_release(&buffer); return -1; } @@ -1805,8 +1805,8 @@ int commit_tree_extended(const char *msg, size_t msg_len, compat_oid = &compat_oid_buf; } - result = write_object_file_flags(buffer.buf, buffer.len, OBJ_COMMIT, - ret, compat_oid, 0); + result = odb_write_object_ext(the_repository->objects, buffer.buf, buffer.len, + OBJ_COMMIT, ret, compat_oid, 0); out: free(parent_buf); strbuf_release(&buffer); diff --git a/git-gui/.gitignore b/git-gui/.gitignore index ff6e0be4b4..5130b4f018 100644 --- a/git-gui/.gitignore +++ b/git-gui/.gitignore @@ -1,8 +1,8 @@ .DS_Store config.mak -Git Gui.app* git-gui.tcl GIT-GUI-BUILD-OPTIONS GIT-VERSION-FILE git-gui +git-gui--askpass lib/tclIndex diff --git a/git-gui/GIT-GUI-BUILD-OPTIONS.in b/git-gui/GIT-GUI-BUILD-OPTIONS.in index 5fd885c2bf..3c112af578 100644 --- a/git-gui/GIT-GUI-BUILD-OPTIONS.in +++ b/git-gui/GIT-GUI-BUILD-OPTIONS.in @@ -4,4 +4,3 @@ GITGUI_RELATIVE=@GITGUI_RELATIVE@ SHELL_PATH=@SHELL_PATH@ TCLTK_PATH=@TCLTK_PATH@ TCL_PATH=@TCL_PATH@ -TKEXECUTABLE=@TKEXECUTABLE@ diff --git a/git-gui/Makefile b/git-gui/Makefile index 8672dd2d6b..27bbe051de 100644 --- a/git-gui/Makefile +++ b/git-gui/Makefile @@ -12,7 +12,6 @@ GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN . $@ uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') -uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not') uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not') SCRIPT_SH = git-gui.sh @@ -54,8 +53,6 @@ INSTALL_R0 = $(INSTALL) -m 644 # space is required here INSTALL_R1 = INSTALL_X0 = $(INSTALL) -m 755 # space is required here INSTALL_X1 = -INSTALL_A0 = find # space is required here -INSTALL_A1 = | cpio -pud INSTALL_L0 = rm -f # space is required here INSTALL_L1 = && ln # space is required here INSTALL_L2 = @@ -80,8 +77,6 @@ ifndef V INSTALL_R1 = && echo ' ' INSTALL 644 `basename $$src` && $(INSTALL) -m 644 $$src INSTALL_X0 = src= INSTALL_X1 = && echo ' ' INSTALL 755 `basename $$src` && $(INSTALL) -m 755 $$src - INSTALL_A0 = src= - INSTALL_A1 = && echo ' ' INSTALL ' ' `basename "$$src"` && find "$$src" | cpio -pud INSTALL_L0 = dst= INSTALL_L1 = && src= @@ -102,18 +97,6 @@ else TCL_PATH ?= $(dir $(TCLTK_PATH))$(notdir $(subst wish,tclsh,$(TCLTK_PATH))) endif -ifeq ($(uname_S),Darwin) - TKFRAMEWORK = /Library/Frameworks/Tk.framework/Resources/Wish.app - ifeq ($(shell echo "$(uname_R)" | awk -F. '{if ($$1 >= 9) print "y"}')_$(shell test -d $(TKFRAMEWORK) || echo n),y_n) - TKFRAMEWORK = /System/Library/Frameworks/Tk.framework/Resources/Wish.app - ifeq ($(shell test -d $(TKFRAMEWORK) || echo n),n) - TKFRAMEWORK = /System/Library/Frameworks/Tk.framework/Resources/Wish\ Shell.app - endif - endif - TKEXECUTABLE = $(TKFRAMEWORK)/Contents/MacOS/$(shell basename "$(TKFRAMEWORK)" .app) - TKEXECUTABLE_SQ = $(subst ','\'',$(TKEXECUTABLE)) -endif - ifeq ($(findstring $(firstword -$(MAKEFLAGS)),s),s) QUIET_GEN = endif @@ -131,16 +114,10 @@ libdir_SQ = $(subst ','\'',$(gg_libdir)) exedir = $(dir $(gitexecdir))share/git-gui/lib GITGUI_RELATIVE := -GITGUI_MACOSXAPP := ifeq ($(exedir),$(gg_libdir)) GITGUI_RELATIVE := 1 endif -ifeq ($(uname_S),Darwin) - ifeq ($(shell test -d $(TKFRAMEWORK) && echo y),y) - GITGUI_MACOSXAPP := YesPlease - endif -endif ifneq (,$(findstring MINGW,$(uname_S))) ifeq ($(shell expr "$(uname_R)" : '1\.'),2) NO_MSGFMT=1 @@ -149,20 +126,6 @@ endif GITGUI_RELATIVE := 1 endif -ifdef GITGUI_MACOSXAPP -GITGUI_MAIN := git-gui.tcl - -git-gui: generate-macos-wrapper.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS - $(QUIET_GEN)$(SHELL_PATH) generate-macos-wrapper.sh "$@" ./GIT-GUI-BUILD-OPTIONS ./GIT-VERSION-FILE - -Git\ Gui.app: GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS \ - macosx/Info.plist \ - macosx/git-gui.icns \ - macosx/AppMain.tcl \ - $(TKEXECUTABLE) - $(QUIET_GEN)$(SHELL_PATH) generate-macos-app.sh . "$@" ./GIT-GUI-BUILD-OPTIONS ./GIT-VERSION-FILE -endif - ifdef GITGUI_WINDOWS_WRAPPER GITGUI_MAIN := git-gui.tcl @@ -170,7 +133,7 @@ git-gui: windows/git-gui.sh cp $< $@ endif -$(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS +$(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS generate-git-gui.sh $(QUIET_GEN)$(SHELL_PATH) generate-git-gui.sh "$<" "$@" ./GIT-GUI-BUILD-OPTIONS ./GIT-VERSION-FILE XGETTEXT ?= xgettext @@ -207,18 +170,17 @@ GIT-GUI-BUILD-OPTIONS: FORCE -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ -e 's|@TCLTK_PATH@|$(TCLTK_PATH_SQ)|' \ -e 's|@TCL_PATH@|$(TCL_PATH_SQ)|' \ - -e 's|@TKEXECUTABLE@|$(TKEXECUTABLE_SQ)|' \ $@.in >$@+ @if grep -q '^[A-Z][A-Z_]*=@.*@$$' $@+; then echo "Unsubstituted build options in $@" >&2 && exit 1; fi @if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi -ifdef GITGUI_MACOSXAPP -all:: git-gui Git\ Gui.app -endif +git-gui--askpass: git-gui--askpass.sh GIT-GUI-BUILD-OPTIONS generate-script.sh + $(QUIET_GEN)$(SHELL_PATH) generate-script.sh $@ $< ./GIT-GUI-BUILD-OPTIONS + ifdef GITGUI_WINDOWS_WRAPPER all:: git-gui endif -all:: $(GITGUI_MAIN) lib/tclIndex $(ALL_MSGFILES) +all:: $(GITGUI_MAIN) git-gui--askpass lib/tclIndex $(ALL_MSGFILES) install: all $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL_D1) @@ -230,10 +192,6 @@ ifdef GITGUI_WINDOWS_WRAPPER endif $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(libdir_SQ)' $(INSTALL_D1) $(QUIET)$(INSTALL_R0)lib/tclIndex $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' -ifdef GITGUI_MACOSXAPP - $(QUIET)$(INSTALL_A0)'Git Gui.app' $(INSTALL_A1) '$(DESTDIR_SQ)$(libdir_SQ)' - $(QUIET)$(INSTALL_X0)git-gui.tcl $(INSTALL_X1) '$(DESTDIR_SQ)$(libdir_SQ)' -endif $(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' &&) true $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(msgsdir_SQ)' $(INSTALL_D1) $(QUIET)$(foreach p,$(ALL_MSGFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(msgsdir_SQ)' &&) true @@ -248,10 +206,6 @@ ifdef GITGUI_WINDOWS_WRAPPER endif $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(libdir_SQ)' $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/tclIndex $(REMOVE_F1) -ifdef GITGUI_MACOSXAPP - $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)/Git Gui.app' $(REMOVE_F1) - $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/git-gui.tcl $(REMOVE_F1) -endif $(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(msgsdir_SQ)' $(QUIET)$(foreach p,$(ALL_MSGFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(msgsdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true @@ -265,11 +219,8 @@ dist-version: GIT-VERSION-FILE @sed 's|^GITGUI_VERSION=||' <GIT-VERSION-FILE >$(TARDIR)/version clean:: - $(RM_RF) $(GITGUI_MAIN) lib/tclIndex po/*.msg $(PO_TEMPLATE) + $(RM_RF) $(GITGUI_MAIN) git-gui--askpass lib/tclIndex po/*.msg $(PO_TEMPLATE) $(RM_RF) GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS -ifdef GITGUI_MACOSXAPP - $(RM_RF) 'Git Gui.app'* git-gui -endif ifdef GITGUI_WINDOWS_WRAPPER $(RM_RF) git-gui endif diff --git a/git-gui/generate-macos-app.sh b/git-gui/generate-macos-app.sh deleted file mode 100755 index 71b9fa67a4..0000000000 --- a/git-gui/generate-macos-app.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - -set -e - -SOURCE_DIR="$1" -OUTPUT="$2" -BUILD_OPTIONS="$3" -VERSION_FILE="$4" - -. "$BUILD_OPTIONS" -. "$VERSION_FILE" - -rm -rf "$OUTPUT" "$OUTPUT+" - -mkdir -p "$OUTPUT+/Contents/MacOS" -mkdir -p "$OUTPUT+/Contents/Resources/Scripts" - -cp "$TKEXECUTABLE" "$OUTPUT+/Contents/MacOS" -cp "$SOURCE_DIR/macosx/git-gui.icns" "$OUTPUT+/Contents/Resources" -sed \ - -e "s/@@GITGUI_VERSION@@/$GITGUI_VERSION/g" \ - -e "s/@@GITGUI_TKEXECUTABLE@@/$(basename "$TKEXECUTABLE")/g" \ - "$SOURCE_DIR/macosx/Info.plist" \ - >"$OUTPUT+/Contents/Info.plist" -sed \ - -e "s|@@gitexecdir@@|$GITGUI_GITEXECDIR|" \ - -e "s|@@GITGUI_LIBDIR@@|$GITGUI_LIBDIR|" \ - "$SOURCE_DIR/macosx/AppMain.tcl" \ - >"$OUTPUT+/Contents/Resources/Scripts/AppMain.tcl" -mv "$OUTPUT+" "$OUTPUT" diff --git a/git-gui/generate-macos-wrapper.sh b/git-gui/generate-macos-wrapper.sh deleted file mode 100755 index 0304937f41..0000000000 --- a/git-gui/generate-macos-wrapper.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -set -e - -if test "$#" -ne 3 -then - echo >&2 "usage: $0 <OUTPUT> <BUILD_OPTIONS> <VERSION_FILE>" - exit 1 -fi - -OUTPUT="$1" -BUILD_OPTIONS="$2" -VERSION_FILE="$3" - -. "$BUILD_OPTIONS" - -rm -f "$OUTPUT" "$OUTPUT+" - -( - echo "#!$SHELL_PATH" - cat "$BUILD_OPTIONS" "$VERSION_FILE" - cat <<-'EOF' - if test "z$*" = zversion || - test "z$*" = z--version - then - echo "git-gui version $GITGUI_VERSION" - else - libdir="${GIT_GUI_LIB_DIR:-$GITGUI_LIBDIR}" - exec "$libdir/Git Gui.app/Contents/MacOS/$(basename "$TKEXECUTABLE")" "$0" "$@" - fi - EOF -) >"$OUTPUT+" - -chmod +x "$OUTPUT+" -mv "$OUTPUT+" "$OUTPUT" diff --git a/git-gui/generate-script.sh b/git-gui/generate-script.sh new file mode 100755 index 0000000000..0dd2da92e3 --- /dev/null +++ b/git-gui/generate-script.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +set -e + +if test $# -ne 3 +then + echo >&2 "USAGE: $0 <OUTPUT> <INPUT> <GIT-GUI-BUILD-OPTIONS>" + exit 1 +fi + +OUTPUT="$1" +INPUT="$2" +BUILD_OPTIONS="$3" + +. "$BUILD_OPTIONS" + +sed \ + -e "1s|#!.*/sh|#!$SHELL_PATH|" \ + -e "1,3s|^exec wish|exec '$TCLTK_PATH'|" \ + "$INPUT" >"$OUTPUT" + +chmod a+x "$OUTPUT" diff --git a/git-gui/git-gui--askpass b/git-gui/git-gui--askpass.sh index 71a536d232..71a536d232 100755 --- a/git-gui/git-gui--askpass +++ b/git-gui/git-gui--askpass.sh diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 8bb121db4f..a931d7f7c9 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -30,7 +30,7 @@ along with this program; if not, see <https://www.gnu.org/licenses/>.}] ## ## Tcl/Tk sanity check -if {[catch {package require Tcl 8.6-8.8} err]} { +if {[catch {package require Tcl 8.6-} err]} { catch {wm withdraw .} tk_messageBox \ -icon error \ @@ -74,6 +74,26 @@ proc is_Cygwin {} { } ###################################################################### +## Enable Tcl8 profile in Tcl9, allowing consumption of data that has +## bytes not conforming to the assumed encoding profile. + +if {[package vcompare $::tcl_version 9.0] >= 0} { + rename open _strict_open + proc open args { + set f [_strict_open {*}$args] + chan configure $f -profile tcl8 + return $f + } + proc convertfrom args { + return [encoding convertfrom -profile tcl8 {*}$args] + } +} else { + proc convertfrom args { + return [encoding convertfrom {*}$args] + } +} + +###################################################################### ## ## PATH lookup. Sanitize $PATH, assure exec/open use only that @@ -83,12 +103,6 @@ if {[is_Windows]} { set _path_sep {:} } -if {[is_Windows]} { - set gitguidir [file dirname [info script]] - regsub -all ";" $gitguidir "\\;" gitguidir - set env(PATH) "$gitguidir;$env(PATH)" -} - set _search_path {} set _path_seen [dict create] foreach p [split $env(PATH) $_path_sep] { @@ -183,7 +197,9 @@ if {[is_Windows]} { set command_line [string trim [string range $arg0 1 end]] lset args 0 "| [sanitize_command_line $command_line 0]" } - uplevel 1 real_open $args + set fd [real_open {*}$args] + fconfigure $fd -eofchar {} + return $fd } } else { @@ -575,8 +591,6 @@ proc _lappend_nice {cmd_var} { set _nice [_which nice] if {[catch {safe_exec [list $_nice git version]}]} { set _nice {} - } elseif {[is_Windows] && [file dirname $_nice] ne [file dirname $::_git]} { - set _nice {} } } if {$_nice ne {}} { @@ -590,7 +604,7 @@ proc git {args} { proc git_redir {cmd redir} { set fd [git_read $cmd $redir] - fconfigure $fd -translation binary -encoding utf-8 + fconfigure $fd -encoding utf-8 set result [string trimright [read $fd] "\n"] close $fd if {$::_trace} { @@ -607,7 +621,6 @@ proc safe_open_command {cmd {redir {}}} { } err]} { error $err } - fconfigure $fd -eofchar {} return $fd } @@ -1003,7 +1016,7 @@ proc _parse_config {arr_name args} { [concat config \ $args \ --null --list]] - fconfigure $fd_rc -translation binary -encoding utf-8 + fconfigure $fd_rc -encoding utf-8 set buf [read $fd_rc] close $fd_rc } @@ -1113,9 +1126,11 @@ citool { ## execution environment # Suggest our implementation of askpass, if none is set +set argv0dir [file dirname [file normalize $::argv0]] if {![info exists env(SSH_ASKPASS)]} { - set env(SSH_ASKPASS) [file join [git --exec-path] git-gui--askpass] + set env(SSH_ASKPASS) [file join $argv0dir git-gui--askpass] } +unset argv0dir ###################################################################### ## @@ -1405,15 +1420,15 @@ proc rescan_stage2 {fd after} { set fd_di [git_read [list diff-index --cached --ignore-submodules=dirty -z [PARENT]]] set fd_df [git_read [list diff-files -z]] - fconfigure $fd_di -blocking 0 -translation binary -encoding binary - fconfigure $fd_df -blocking 0 -translation binary -encoding binary + fconfigure $fd_di -blocking 0 -translation binary + fconfigure $fd_df -blocking 0 -translation binary fileevent $fd_di readable [list read_diff_index $fd_di $after] fileevent $fd_df readable [list read_diff_files $fd_df $after] if {[is_config_true gui.displayuntracked]} { set fd_lo [git_read [concat ls-files --others -z $ls_others]] - fconfigure $fd_lo -blocking 0 -translation binary -encoding binary + fconfigure $fd_lo -blocking 0 -translation binary fileevent $fd_lo readable [list read_ls_others $fd_lo $after] incr rescan_active } @@ -1427,7 +1442,6 @@ proc load_message {file {encoding {}}} { if {[catch {set fd [safe_open_file $f r]}]} { return 0 } - fconfigure $fd -eofchar {} if {$encoding ne {}} { fconfigure $fd -encoding $encoding } @@ -1484,7 +1498,7 @@ proc run_prepare_commit_msg_hook {} { ui_status [mc "Calling prepare-commit-msg hook..."] set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable \ [list prepare_commit_msg_hook_wait $fd_ph] @@ -1530,7 +1544,7 @@ proc read_diff_index {fd after} { set i [split [string range $buf_rdi $c [expr {$z1 - 2}]] { }] set p [string range $buf_rdi $z1 [expr {$z2 - 1}]] merge_state \ - [encoding convertfrom utf-8 $p] \ + [convertfrom utf-8 $p] \ [lindex $i 4]? \ [list [lindex $i 0] [lindex $i 2]] \ [list] @@ -1563,7 +1577,7 @@ proc read_diff_files {fd after} { set i [split [string range $buf_rdf $c [expr {$z1 - 2}]] { }] set p [string range $buf_rdf $z1 [expr {$z2 - 1}]] merge_state \ - [encoding convertfrom utf-8 $p] \ + [convertfrom utf-8 $p] \ ?[lindex $i 4] \ [list] \ [list [lindex $i 0] [lindex $i 2]] @@ -1586,7 +1600,7 @@ proc read_ls_others {fd after} { set pck [split $buf_rlo "\0"] set buf_rlo [lindex $pck end] foreach p [lrange $pck 0 end-1] { - set p [encoding convertfrom utf-8 $p] + set p [convertfrom utf-8 $p] if {[string index $p end] eq {/}} { set p [string range $p 0 end-1] } diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl index 9d4d1ac872..4477b84eae 100644 --- a/git-gui/lib/blame.tcl +++ b/git-gui/lib/blame.tcl @@ -483,7 +483,6 @@ method _load {jump} { } else { set fd [safe_open_file $path r] } - fconfigure $fd -eofchar {} } else { if {$do_textconv ne 0} { set fd [git_read [list cat-file --textconv "$commit:$path"]] @@ -493,7 +492,6 @@ method _load {jump} { } fconfigure $fd \ -blocking 0 \ - -translation lf \ -encoding [get_path_encoding $path] fileevent $fd readable [cb _read_file $fd $jump] set current_fd $fd @@ -620,7 +618,7 @@ method _exec_blame {cur_w cur_d options cur_s} { lappend options -- $path set fd [git_read_nice [concat blame $options]] - fconfigure $fd -blocking 0 -translation lf -encoding utf-8 + fconfigure $fd -blocking 0 -encoding utf-8 fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d] set current_fd $fd set blame_lines 0 @@ -986,7 +984,7 @@ method _showcommit {cur_w lno} { set msg {} catch { set fd [git_read [list cat-file commit $cmit]] - fconfigure $fd -encoding binary -translation lf + fconfigure $fd -encoding iso8859-1 # By default commits are assumed to be in utf-8 set enc utf-8 while {[gets $fd line] > 0} { @@ -999,7 +997,7 @@ method _showcommit {cur_w lno} { set enc [tcl_encoding $enc] if {$enc ne {}} { - set msg [encoding convertfrom $enc $msg] + set msg [convertfrom $enc $msg] } set msg [string trim $msg] } @@ -1143,7 +1141,6 @@ method _blameparent {} { fconfigure $fd \ -blocking 0 \ - -encoding binary \ -translation binary fileevent $fd readable [cb _read_diff_load_commit \ $fd $cparent $new_path $r_orig_line] diff --git a/git-gui/lib/branch.tcl b/git-gui/lib/branch.tcl index 39e0f2dc98..97c9ec1c00 100644 --- a/git-gui/lib/branch.tcl +++ b/git-gui/lib/branch.tcl @@ -8,7 +8,7 @@ proc load_all_heads {} { set rh_len [expr {[string length $rh] + 1}] set all_heads [list] set fd [git_read [list for-each-ref --format=%(refname) $rh]] - fconfigure $fd -translation binary -encoding utf-8 + fconfigure $fd -encoding utf-8 while {[gets $fd line] > 0} { if {!$some_heads_tracking || ![is_tracking_branch $line]} { lappend all_heads [string range $line $rh_len end] @@ -25,7 +25,7 @@ proc load_all_tags {} { --sort=-taggerdate \ --format=%(refname) \ refs/tags]] - fconfigure $fd -translation binary -encoding utf-8 + fconfigure $fd -encoding utf-8 while {[gets $fd line] > 0} { if {![regsub ^refs/tags/ $line {} name]} continue lappend all_tags $name diff --git a/git-gui/lib/browser.tcl b/git-gui/lib/browser.tcl index f53eb952cf..fe72de025e 100644 --- a/git-gui/lib/browser.tcl +++ b/git-gui/lib/browser.tcl @@ -195,7 +195,7 @@ method _ls {tree_id {name {}}} { $w conf -state disabled set fd [git_read [list ls-tree -z $tree_id]] - fconfigure $fd -blocking 0 -translation binary -encoding utf-8 + fconfigure $fd -blocking 0 -encoding utf-8 fileevent $fd readable [cb _read $fd] } diff --git a/git-gui/lib/checkout_op.tcl b/git-gui/lib/checkout_op.tcl index 987486a4b6..449e89e2bc 100644 --- a/git-gui/lib/checkout_op.tcl +++ b/git-gui/lib/checkout_op.tcl @@ -462,7 +462,7 @@ If you wanted to be on a branch, create one now starting from 'This Detached Che if {$fd_ph ne {}} { global pch_error set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable [cb _postcheckout_wait $fd_ph] } else { _update_repo_state $this diff --git a/git-gui/lib/choose_rev.tcl b/git-gui/lib/choose_rev.tcl index 7a9e3c83bb..cd355cc92a 100644 --- a/git-gui/lib/choose_rev.tcl +++ b/git-gui/lib/choose_rev.tcl @@ -147,7 +147,7 @@ constructor _new {path unmerged_only title} { refs/remotes \ refs/tags \ ]] - fconfigure $fr_fd -translation lf -encoding utf-8 + fconfigure $fr_fd -encoding utf-8 while {[gets $fr_fd line] > 0} { set line [eval $line] if {[lindex $line 1 0] eq {tag}} { @@ -570,7 +570,7 @@ method _reflog_last {name} { set last {} if {[catch {set last [file mtime [gitdir $name]]}] && ![catch {set g [safe_open_file [gitdir logs $name] r]}]} { - fconfigure $g -translation binary + fconfigure $g -encoding iso8859-1 while {[gets $g line] >= 0} { if {[regexp {> ([1-9][0-9]*) } $line line when]} { set last $when diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 2fd57a51fb..89eb8c7b73 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -28,7 +28,7 @@ You are currently in the middle of a merge that has not been fully completed. Y set name "" set email "" set fd [git_read [list cat-file commit $curHEAD]] - fconfigure $fd -encoding binary -translation lf + fconfigure $fd -encoding iso8859-1 # By default commits are assumed to be in utf-8 set enc utf-8 while {[gets $fd line] > 0} { @@ -43,9 +43,9 @@ You are currently in the middle of a merge that has not been fully completed. Y set enc [tcl_encoding $enc] if {$enc ne {}} { - set msg [encoding convertfrom $enc $msg] - set name [encoding convertfrom $enc $name] - set email [encoding convertfrom $enc $email] + set msg [convertfrom $enc $msg] + set name [convertfrom $enc $name] + set email [convertfrom $enc $email] } if {$name ne {} && $email ne {}} { set commit_author [list name $name email $email date $time] @@ -208,28 +208,6 @@ You must stage at least 1 file before you can commit. # -- A message is required. # set msg [$ui_comm get 1.0 end] - # Strip trailing whitespace - regsub -all -line {[ \t\r]+$} $msg {} msg - # Strip comment lines - global comment_string - set cmt_rx [strcat {(^|\n)} [regsub -all {\W} $comment_string {\\&}] {[^\n]*}] - regsub -all $cmt_rx $msg {\1} msg - # Strip leading and trailing empty lines (puts adds one \n) - set msg [string trim $msg \n] - # Compress consecutive empty lines - regsub -all {\n{3,}} $msg "\n\n" msg - if {$msg eq {}} { - error_popup [mc "Please supply a commit message. - -A good commit message has the following format: - -- First line: Describe in one sentence what you did. -- Second line: Blank -- Remaining lines: Describe why this change is good. -"] - unlock_index - return - } # -- Build the message file. # @@ -252,7 +230,7 @@ A good commit message has the following format: ui_status [mc "Calling pre-commit hook..."] set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable \ [list commit_prehook_wait $fd_ph $curHEAD $msg_p] } @@ -307,7 +285,7 @@ Do you really want to proceed with your Commit?"] ui_status [mc "Calling commit-msg hook..."] set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable \ [list commit_commitmsg_wait $fd_ph $curHEAD $msg_p] } @@ -332,7 +310,52 @@ proc commit_commitmsg_wait {fd_ph curHEAD msg_p} { fconfigure $fd_ph -blocking 0 } +proc wash_commit_message {msg} { + # Strip trailing whitespace + regsub -all -line {[ \t\r]+$} $msg {} msg + # Strip comment lines + global comment_string + set cmt_rx [strcat {(^|\n)} [regsub -all {\W} $comment_string {\\&}] {[^\n]*}] + regsub -all $cmt_rx $msg {\1} msg + # Strip leading and trailing empty lines (puts adds one \n) + set msg [string trim $msg \n] + # Compress consecutive empty lines + regsub -all {\n{3,}} $msg \n\n msg + + return $msg +} + proc commit_writetree {curHEAD msg_p} { + # -- Process the commit message after hooks have run. + # + set msg_fd [safe_open_file $msg_p r] + setup_commit_encoding $msg_fd 1 + set msg [read $msg_fd] + close $msg_fd + + # Process the message (strip whitespace, comments, etc.) + set msg [wash_commit_message $msg] + + if {$msg eq {}} { + error_popup [mc "Please supply a commit message. + +A good commit message has the following format: + +- First line: Describe in one sentence what you did. +- Second line: Blank +- Remaining lines: Describe why this change is good. +"] + unlock_index + return + } + + # Write the processed message back to the file + set msg_wt [safe_open_file $msg_p w] + fconfigure $msg_wt -translation lf + setup_commit_encoding $msg_wt + puts $msg_wt $msg + close $msg_wt + ui_status [mc "Committing changes..."] set fd_wt [git_read [list write-tree]] fileevent $fd_wt readable \ @@ -361,7 +384,7 @@ proc commit_committree {fd_wt curHEAD msg_p} { # if {$commit_type eq {normal}} { set fd_ot [git_read [list cat-file commit $PARENT]] - fconfigure $fd_ot -encoding binary -translation lf + fconfigure $fd_ot -encoding iso8859-1 set old_tree [gets $fd_ot] close $fd_ot @@ -460,7 +483,7 @@ A rescan will be automatically started now. if {$fd_ph ne {}} { global pch_error set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable \ [list commit_postcommit_wait $fd_ph $cmt_id] } diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl index 1acd37bdb4..442737ba4f 100644 --- a/git-gui/lib/diff.tcl +++ b/git-gui/lib/diff.tcl @@ -191,7 +191,6 @@ proc show_other_diff {path w m cont_info} { file { set fd [safe_open_file $path r] fconfigure $fd \ - -eofchar {} \ -encoding [get_path_encoding $path] set content [read $fd $max_sz] close $fd @@ -325,6 +324,8 @@ proc start_show_diff {cont_info {add_opts {}}} { # '++' lines which is not bijective. Thus, we need to maintain a state # across lines. set ::conflict_in_pre_image 0 + + # git-diff has eol==\n, \r if present is part of the text fconfigure $fd \ -blocking 0 \ -encoding [get_path_encoding $path] \ diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl index 377547034b..7aa09c7728 100644 --- a/git-gui/lib/index.tcl +++ b/git-gui/lib/index.tcl @@ -78,7 +78,6 @@ proc update_indexinfo {msg path_list after} { -blocking 0 \ -buffering full \ -buffersize 512 \ - -encoding binary \ -translation binary fileevent $fd writable [list \ write_update_indexinfo \ @@ -147,7 +146,6 @@ proc update_index {msg path_list after} { -blocking 0 \ -buffering full \ -buffersize 512 \ - -encoding binary \ -translation binary fileevent $fd writable [list \ write_update_index \ @@ -227,7 +225,6 @@ proc checkout_index {msg path_list after capture_error} { -blocking 0 \ -buffering full \ -buffersize 512 \ - -encoding binary \ -translation binary fileevent $fd writable [list \ write_checkout_index \ diff --git a/git-gui/lib/mergetool.tcl b/git-gui/lib/mergetool.tcl index 2c9bb3af40..44be4ed3ff 100644 --- a/git-gui/lib/mergetool.tcl +++ b/git-gui/lib/mergetool.tcl @@ -90,7 +90,7 @@ proc merge_load_stages {path cont} { set merge_stages_fd [git_read [list ls-files -u -z -- $path]] - fconfigure $merge_stages_fd -blocking 0 -translation binary -encoding binary + fconfigure $merge_stages_fd -blocking 0 -translation binary fileevent $merge_stages_fd readable [list read_merge_stages $merge_stages_fd $cont] } @@ -370,7 +370,7 @@ proc merge_tool_start {cmdline target backup stages} { ui_status [mc "Running merge tool..."] - fconfigure $mtool_fd -blocking 0 -translation binary -encoding binary + fconfigure $mtool_fd -blocking 0 -translation binary fileevent $mtool_fd readable [list read_mtool_output $mtool_fd] } diff --git a/git-gui/lib/remote_branch_delete.tcl b/git-gui/lib/remote_branch_delete.tcl index 349d31edf3..f0814efdd7 100644 --- a/git-gui/lib/remote_branch_delete.tcl +++ b/git-gui/lib/remote_branch_delete.tcl @@ -307,7 +307,6 @@ method _load {cache uri} { set active_ls [git_read [list ls-remote $uri]] fconfigure $active_ls \ -blocking 0 \ - -translation lf \ -encoding utf-8 fileevent $active_ls readable [cb _read $cache $active_ls] } else { diff --git a/git-gui/lib/shortcut.tcl b/git-gui/lib/shortcut.tcl index 1d01d9cbfa..431665059e 100644 --- a/git-gui/lib/shortcut.tcl +++ b/git-gui/lib/shortcut.tcl @@ -3,27 +3,41 @@ proc do_windows_shortcut {} { global _gitworktree - set fn [tk_getSaveFile \ - -parent . \ - -title [mc "%s (%s): Create Desktop Icon" [appname] [reponame]] \ - -initialfile "Git [reponame].lnk"] - if {$fn != {}} { - if {[file extension $fn] ne {.lnk}} { - set fn ${fn}.lnk - } - # Use git-gui.exe if available (ie: git-for-windows) - set cmdLine [list [_which git-gui]] - if {$cmdLine eq {}} { - set cmdLine [list [info nameofexecutable] \ - [file normalize $::argv0]] - } - if {[catch { - win32_create_lnk $fn $cmdLine \ - [file normalize $_gitworktree] - } err]} { - error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"] + + set desktop [safe_exec [list cygpath -mD]] + set link_file "Git [reponame].lnk" + set link_path [file normalize [file join $desktop $link_file]] + + # on Windows, tk_getSaveFile dereferences .lnk files, so no simple + # filename chooser is available. Use the default or quit. + if {[file exists $link_path]} { + set answer [tk_messageBox \ + -type yesno \ + -title [mc "%s (%s): Create Desktop Icon" [appname] [reponame]] \ + -default yes \ + -message [mc "Replace existing shortcut: %s?" $link_file]] + if {$answer == no} { + return } } + + # Use git-gui.exe if found, fall back to wish + launcher + set link_arguments {} + set link_target [safe_exec [list cygpath -m /cmd/git-gui.exe]] + if {![file executable $link_target]} { + set link_target [_which git-gui] + } + if {![file executable $link_target]} { + set link_target [file normalize [info nameofexecutable]] + set link_arguments [file normalize $::argv0] + } + set cmdLine [list $link_target $link_arguments] + if {[catch { + win32_create_lnk $link_path $cmdLine \ + [file normalize $_gitworktree] + } err]} { + error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"] + } } proc do_cygwin_shortcut {} { diff --git a/git-gui/lib/spellcheck.tcl b/git-gui/lib/spellcheck.tcl index 538d61c792..634656820d 100644 --- a/git-gui/lib/spellcheck.tcl +++ b/git-gui/lib/spellcheck.tcl @@ -33,7 +33,6 @@ constructor init {pipe_fd ui_text ui_menu} { method _connect {pipe_fd} { fconfigure $pipe_fd \ -encoding utf-8 \ - -eofchar {} \ -translation lf if {[gets $pipe_fd s_version] <= 0} { diff --git a/git-gui/lib/themed.tcl b/git-gui/lib/themed.tcl index 8c4a0c2ee7..c18e201d85 100644 --- a/git-gui/lib/themed.tcl +++ b/git-gui/lib/themed.tcl @@ -21,10 +21,10 @@ namespace eval color { set inactive_select_bg [convert_rgb_to_gray $select_bg] set inactive_select_fg $select_fg - set color::select_bg $select_bg - set color::select_fg $select_fg - set color::inactive_select_bg $inactive_select_bg - set color::inactive_select_fg $inactive_select_fg + set ::color::select_bg $select_bg + set ::color::select_fg $select_fg + set ::color::inactive_select_bg $inactive_select_bg + set ::color::inactive_select_fg $inactive_select_fg proc add_option {key val} { option add $key $val widgetDefault diff --git a/git-gui/macosx/AppMain.tcl b/git-gui/macosx/AppMain.tcl deleted file mode 100644 index b6c6dc3500..0000000000 --- a/git-gui/macosx/AppMain.tcl +++ /dev/null @@ -1,29 +0,0 @@ -set gitexecdir {@@gitexecdir@@} -if { [info exists ::env(GIT_GUI_LIB_DIR) ] } { - set gitguilib $::env(GIT_GUI_LIB_DIR) -} else { - set gitguilib {@@GITGUI_LIBDIR@@} -} - -set env(PATH) "$gitexecdir:$env(PATH)" - -if {[string first -psn [lindex $argv 0]] == 0} { - lset argv 0 [file join $gitexecdir git-gui] -} - -if {[file tail [lindex $argv 0]] eq {gitk}} { - set argv0 [lindex $argv 0] - set AppMain_source $argv0 -} else { - set argv0 [file join $gitexecdir [file tail [lindex $argv 0]]] - set AppMain_source [file join $gitguilib git-gui.tcl] - if {[info exists env(PWD)]} { - cd $env(PWD) - } elseif {[pwd] eq {/}} { - cd $env(HOME) - } -} - -unset gitexecdir gitguilib -set argv [lrange $argv 1 end] -source $AppMain_source diff --git a/git-gui/macosx/Info.plist b/git-gui/macosx/Info.plist deleted file mode 100644 index 1ade121c4c..0000000000 --- a/git-gui/macosx/Info.plist +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>@@GITGUI_TKEXECUTABLE@@</string> - <key>CFBundleGetInfoString</key> - <string>Git Gui @@GITGUI_VERSION@@ © 2006-2007 Shawn Pearce, et. al.</string> - <key>CFBundleIconFile</key> - <string>git-gui.icns</string> - <key>CFBundleIdentifier</key> - <string>cz.or.repo.git-gui</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>Git Gui</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>@@GITGUI_VERSION@@</string> - <key>CFBundleSignature</key> - <string>GITg</string> - <key>CFBundleVersion</key> - <string>@@GITGUI_VERSION@@</string> - <key>NSHighResolutionCapable</key> - <true/> -</dict> -</plist> diff --git a/git-gui/macosx/git-gui.icns b/git-gui/macosx/git-gui.icns Binary files differdeleted file mode 100644 index 77d88a77a7..0000000000 --- a/git-gui/macosx/git-gui.icns +++ /dev/null diff --git a/git-gui/meson.build b/git-gui/meson.build index cdae85e4b9..320ba09ecf 100644 --- a/git-gui/meson.build +++ b/git-gui/meson.build @@ -19,17 +19,6 @@ build_options_config.set_quoted('GITGUI_LIBDIR', get_option('prefix') / get_opti build_options_config.set_quoted('SHELL_PATH', fs.as_posix(shell.full_path())) build_options_config.set_quoted('TCLTK_PATH', fs.as_posix(wish.full_path())) build_options_config.set_quoted('TCL_PATH', fs.as_posix(tclsh.full_path())) -if target_machine.system() == 'darwin' - tkexecutables = [ - '/Library/Frameworks/Tk.framework/Resources/Wish.app/Contents/MacOS/Wish', - '/System/Library/Frameworks/Tk.framework/Resources/Wish.app/Contents/MacOS/Wish', - '/System/Library/Frameworks/Tk.framework/Resources/Wish Shell.app/Contents/MacOS/Wish Shell', - ] - tkexecutable = find_program(tkexecutables) - build_options_config.set_quoted('TKEXECUTABLE', tkexecutable.full_path()) -else - build_options_config.set('TKEXECUTABLE', '') -endif build_options = configure_file( input: 'GIT-GUI-BUILD-OPTIONS.in', @@ -49,14 +38,6 @@ version_file = custom_target( build_always_stale: true, ) -configure_file( - input: 'git-gui--askpass', - output: 'git-gui--askpass', - copy: true, - install: true, - install_dir: get_option('libexecdir') / 'git-core', -) - gitgui_main = 'git-gui' gitgui_main_install_dir = get_option('libexecdir') / 'git-core' @@ -70,55 +51,23 @@ if target_machine.system() == 'windows' install: true, install_dir: get_option('libexecdir') / 'git-core', ) -elif target_machine.system() == 'darwin' - gitgui_main = 'git-gui.tcl' - gitgui_main_install_dir = get_option('datadir') / 'git-gui/lib' - - custom_target( - output: 'git-gui', - command: [ - shell, - meson.current_source_dir() / 'generate-macos-wrapper.sh', - '@OUTPUT@', - meson.current_build_dir() / 'GIT-GUI-BUILD-OPTIONS', - meson.current_build_dir() / 'GIT-VERSION-FILE', - ], - depends: [ - version_file, - ], - depend_files: [ - build_options, - ], - install: true, - install_dir: get_option('libexecdir') / 'git-core', - ) - - custom_target( - output: 'Git Gui.app', - command: [ - shell, - meson.current_source_dir() / 'generate-macos-app.sh', - meson.current_source_dir(), - meson.current_build_dir() / 'Git Gui.app', - meson.current_build_dir() / 'GIT-GUI-BUILD-OPTIONS', - meson.current_build_dir() / 'GIT-VERSION-FILE', - ], - depends: [ - version_file, - ], - depend_files: [ - build_options, - 'macosx/AppMain.tcl', - 'macosx/Info.plist', - 'macosx/git-gui.icns', - ], - build_by_default: true, - install: true, - install_dir: get_option('datadir') / 'git-gui/lib', - ) endif custom_target( + output: 'git-gui--askpass', + input: 'git-gui--askpass.sh', + command: [ + shell, + meson.current_source_dir() / 'generate-script.sh', + '@OUTPUT@', + '@INPUT@', + meson.current_build_dir() / 'GIT-GUI-BUILD-OPTIONS', + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +custom_target( input: 'git-gui.sh', output: gitgui_main, command: [ diff --git a/git-gui/po/bg.po b/git-gui/po/bg.po index 70ab2b438a..21f5bd54e9 100644 --- a/git-gui/po/bg.po +++ b/git-gui/po/bg.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: git-gui master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-20 09:27+0200\n" -"PO-Revision-Date: 2025-05-29 13:37+0200\n" +"POT-Creation-Date: 2025-07-22 17:37+0200\n" +"PO-Revision-Date: 2025-07-28 11:56+0200\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -18,88 +18,58 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: git-gui.sh:861 #, tcl-format msgid "Invalid font specified in %s:" msgstr "Указан е неправилен шрифт в „%s“:" -#: git-gui.sh:924 msgid "Main Font" msgstr "Основен шрифт" -#: git-gui.sh:925 msgid "Diff/Console Font" msgstr "Шрифт за разликите/конзолата" -#: git-gui.sh:940 git-gui.sh:954 git-gui.sh:967 git-gui.sh:1057 git-gui.sh:1076 -#: git-gui.sh:3217 msgid "git-gui: fatal error" msgstr "git-gui: фатална грешка" -#: git-gui.sh:941 msgid "Cannot find git in PATH." msgstr "Командата git липсва в пътя (PATH)." -#: git-gui.sh:968 msgid "Cannot parse Git version string:" msgstr "Низът с версията на Git не може да се анализира:" -#: git-gui.sh:993 -#, tcl-format -msgid "" -"Git version cannot be determined.\n" -"\n" -"%s claims it is version '%s'.\n" -"\n" -"%s requires at least Git 1.5.0 or later.\n" -"\n" -"Assume '%s' is version 1.5.0?\n" -msgstr "" -"Версията на Git не може да се определи.\n" -"\n" -"Версията на „%s“ изглежда, че е „%s“.\n" -"\n" -"„%s“ изисква Git, версия поне 1.5.0.\n" -"\n" -"Да се приеме ли, че „%s“ е версия „1.5.0“?\n" +msgid "Insufficient git version, require: " +msgstr "Прекалено ниска версия на git, необходима е поне: " + +msgid "git returned:" +msgstr "git върна:" -#: git-gui.sh:1287 msgid "Git directory not found:" msgstr "Директорията на Git не е открита:" -#: git-gui.sh:1317 msgid "Cannot move to top of working directory:" msgstr "Не може да се премине към родителската директория." -#: git-gui.sh:1325 msgid "Cannot use bare repository:" msgstr "Голо хранилище не може да се използва:" -#: git-gui.sh:1333 msgid "No working directory" msgstr "Работната директория липсва" -#: git-gui.sh:1507 lib/checkout_op.tcl:306 msgid "Refreshing file status..." msgstr "Обновяване на състоянието на файла…" -#: git-gui.sh:1551 msgid "Scanning for modified files ..." msgstr "Проверка за променени файлове…" -#: git-gui.sh:1635 msgid "Calling prepare-commit-msg hook..." msgstr "Куката „prepare-commit-msg“ се изпълнява в момента…" -#: git-gui.sh:1652 msgid "Commit declined by prepare-commit-msg hook." msgstr "Подаването е отхвърлено от куката „prepare-commit-msg“." -#: git-gui.sh:1810 lib/browser.tcl:252 msgid "Ready." msgstr "Готово." -#: git-gui.sh:1974 #, tcl-format msgid "" "Display limit (gui.maxfilesdisplayed = %s) reached, not showing all %s files." @@ -108,721 +78,539 @@ msgstr "" "извеждане(gui.maxfilesdisplayed = %s), съответно не са показани всички %s " "файла." -#: git-gui.sh:2097 msgid "Unmodified" msgstr "Непроменен" -#: git-gui.sh:2099 msgid "Modified, not staged" msgstr "Променен, но не е в индекса" -#: git-gui.sh:2100 git-gui.sh:2112 msgid "Staged for commit" msgstr "В индекса за подаване" -#: git-gui.sh:2101 git-gui.sh:2113 msgid "Portions staged for commit" msgstr "Части са в индекса за подаване" -#: git-gui.sh:2102 git-gui.sh:2114 msgid "Staged for commit, missing" msgstr "В индекса за подаване, но липсва" -#: git-gui.sh:2104 msgid "File type changed, not staged" msgstr "Видът на файла е сменен, но не е в индекса" -#: git-gui.sh:2105 git-gui.sh:2106 msgid "File type changed, old type staged for commit" msgstr "Видът на файла е сменен, но новият вид не е в индекса" -#: git-gui.sh:2107 msgid "File type changed, staged" msgstr "Видът на файла е сменен и е в индекса" -#: git-gui.sh:2108 msgid "File type change staged, modification not staged" msgstr "Видът на файла е сменен в индекса, но не и съдържанието" -#: git-gui.sh:2109 msgid "File type change staged, file missing" msgstr "Видът на файла е сменен в индекса, но файлът липсва" -#: git-gui.sh:2111 msgid "Untracked, not staged" msgstr "Неследен" -#: git-gui.sh:2116 msgid "Missing" msgstr "Липсващ" -#: git-gui.sh:2117 msgid "Staged for removal" msgstr "В индекса за изтриване" -#: git-gui.sh:2118 msgid "Staged for removal, still present" msgstr "В индекса за изтриване, но още го има" -#: git-gui.sh:2120 git-gui.sh:2121 git-gui.sh:2122 git-gui.sh:2123 -#: git-gui.sh:2124 git-gui.sh:2125 msgid "Requires merge resolution" msgstr "Изисква коригиране при сливане" -#: git-gui.sh:2170 msgid "Couldn't find gitk in PATH" msgstr "Командата „gitk“ липсва в пътищата, определени от променливата PATH." -#: git-gui.sh:2217 git-gui.sh:2253 #, tcl-format msgid "Starting %s... please wait..." msgstr "Стартиране на „%s“…, изчакайте…" -#: git-gui.sh:2232 msgid "Couldn't find git gui in PATH" msgstr "" "Командата „git gui“ липсва в пътищата, определени от променливата PATH." -#: git-gui.sh:2735 lib/choose_repository.tcl:53 msgid "Repository" msgstr "Хранилище" -#: git-gui.sh:2736 msgid "Edit" msgstr "Редактиране" -#: git-gui.sh:2738 lib/choose_rev.tcl:567 msgid "Branch" msgstr "Клон" -#: git-gui.sh:2741 lib/choose_rev.tcl:554 msgid "Commit@@noun" msgstr "Подаване" -#: git-gui.sh:2744 lib/merge.tcl:127 lib/merge.tcl:174 msgid "Merge" msgstr "Сливане" -#: git-gui.sh:2745 lib/choose_rev.tcl:563 msgid "Remote" msgstr "Отдалечено хранилище" -#: git-gui.sh:2748 msgid "Tools" msgstr "Команди" -#: git-gui.sh:2757 msgid "Explore Working Copy" msgstr "Разглеждане на работното копие" -#: git-gui.sh:2772 msgid "Git Bash" msgstr "Bash за Git" -#: git-gui.sh:2781 msgid "Browse Current Branch's Files" msgstr "Разглеждане на файловете в текущия клон" -#: git-gui.sh:2785 msgid "Browse Branch Files..." msgstr "Разглеждане на текущия клон…" -#: git-gui.sh:2790 msgid "Visualize Current Branch's History" msgstr "Визуализация на историята на текущия клон" -#: git-gui.sh:2794 msgid "Visualize All Branch History" msgstr "Визуализация на историята на всички клонове" -#: git-gui.sh:2801 #, tcl-format msgid "Browse %s's Files" msgstr "Разглеждане на файловете в „%s“" -#: git-gui.sh:2803 #, tcl-format msgid "Visualize %s's History" msgstr "Визуализация на историята на „%s“" -#: git-gui.sh:2808 lib/database.tcl:40 msgid "Database Statistics" msgstr "Статистика на базата от данни" -#: git-gui.sh:2811 lib/database.tcl:33 msgid "Compress Database" msgstr "Компресиране на базата от данни" -#: git-gui.sh:2814 msgid "Verify Database" msgstr "Проверка на базата от данни" -#: git-gui.sh:2821 git-gui.sh:2825 git-gui.sh:2829 msgid "Create Desktop Icon" msgstr "Добавяне на икона на работния плот" -#: git-gui.sh:2837 lib/choose_repository.tcl:206 lib/choose_repository.tcl:214 msgid "Quit" msgstr "Спиране на програмата" -#: git-gui.sh:2845 msgid "Undo" msgstr "Отмяна" -#: git-gui.sh:2848 msgid "Redo" msgstr "Повторение" -#: git-gui.sh:2852 git-gui.sh:3477 msgid "Cut" msgstr "Отрязване" -#: git-gui.sh:2855 git-gui.sh:3480 git-gui.sh:3556 git-gui.sh:3651 -#: lib/console.tcl:69 msgid "Copy" msgstr "Копиране" -#: git-gui.sh:2858 git-gui.sh:3483 msgid "Paste" msgstr "Поставяне" -#: git-gui.sh:2861 git-gui.sh:3486 lib/branch_delete.tcl:28 -#: lib/remote_branch_delete.tcl:39 msgid "Delete" msgstr "Изтриване" -#: git-gui.sh:2865 git-gui.sh:3490 git-gui.sh:3655 lib/console.tcl:71 msgid "Select All" msgstr "Избиране на всичко" -#: git-gui.sh:2874 msgid "Create..." msgstr "Създаване…" -#: git-gui.sh:2880 msgid "Checkout..." msgstr "Изтегляне…" -#: git-gui.sh:2886 msgid "Rename..." msgstr "Преименуване…" -#: git-gui.sh:2891 msgid "Delete..." msgstr "Изтриване…" -#: git-gui.sh:2896 msgid "Reset..." msgstr "Отмяна на промените…" -#: git-gui.sh:2906 msgid "Done" msgstr "Готово" -#: git-gui.sh:2908 msgid "Commit@@verb" msgstr "Подаване" -#: git-gui.sh:2917 git-gui.sh:3416 msgid "Amend Last Commit" msgstr "Поправяне на последното подаване" -#: git-gui.sh:2927 git-gui.sh:3377 lib/remote_branch_delete.tcl:101 msgid "Rescan" msgstr "Обновяване" -#: git-gui.sh:2933 msgid "Stage To Commit" msgstr "Към индекса за подаване" -#: git-gui.sh:2939 msgid "Stage Changed Files To Commit" msgstr "Всички променени файлове към индекса за подаване" -#: git-gui.sh:2945 msgid "Unstage From Commit" msgstr "Изваждане от индекса за подаване" -#: git-gui.sh:2951 lib/index.tcl:521 msgid "Revert Changes" msgstr "Връщане на оригинала" -#: git-gui.sh:2959 git-gui.sh:3718 git-gui.sh:3749 msgid "Show Less Context" msgstr "По-малко контекст" -#: git-gui.sh:2963 git-gui.sh:3722 git-gui.sh:3753 msgid "Show More Context" msgstr "Повече контекст" -#: git-gui.sh:2970 git-gui.sh:3390 git-gui.sh:3501 msgid "Sign Off" msgstr "Подписване" -#: git-gui.sh:2986 msgid "Local Merge..." msgstr "Локално сливане…" -#: git-gui.sh:2991 msgid "Abort Merge..." msgstr "Преустановяване на сливане…" -#: git-gui.sh:3003 git-gui.sh:3031 msgid "Add..." msgstr "Добавяне…" -#: git-gui.sh:3007 msgid "Push..." msgstr "Изтласкване…" -#: git-gui.sh:3011 msgid "Delete Branch..." msgstr "Изтриване на клон…" -#: git-gui.sh:3021 git-gui.sh:3684 msgid "Options..." msgstr "Опции…" -#: git-gui.sh:3032 msgid "Remove..." msgstr "Премахване…" -#: git-gui.sh:3041 lib/choose_repository.tcl:67 msgid "Help" msgstr "Помощ" -#: git-gui.sh:3045 git-gui.sh:3049 lib/about.tcl:14 -#: lib/choose_repository.tcl:61 lib/choose_repository.tcl:70 #, tcl-format msgid "About %s" msgstr "Относно „%s“" -#: git-gui.sh:3069 msgid "Online Documentation" msgstr "Документация в Интернет" -#: git-gui.sh:3072 lib/choose_repository.tcl:64 lib/choose_repository.tcl:73 msgid "Show SSH Key" msgstr "Показване на ключа за SSH" -#: git-gui.sh:3102 git-gui.sh:3234 msgid "usage:" msgstr "употреба:" -#: git-gui.sh:3106 git-gui.sh:3238 msgid "Usage" msgstr "Употреба" -#: git-gui.sh:3187 lib/blame.tcl:576 msgid "Error" msgstr "Грешка" -#: git-gui.sh:3218 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "ФАТАЛНА ГРЕШКА: пътят „%s“ липсва: такъв файл или директория няма" -#: git-gui.sh:3251 msgid "Current Branch:" msgstr "Текущ клон:" -#: git-gui.sh:3276 msgid "Unstaged Changes" msgstr "Промени извън индекса" -#: git-gui.sh:3298 msgid "Staged Changes (Will Commit)" msgstr "Промени в индекса (за подаване)" -#: git-gui.sh:3383 msgid "Stage Changed" msgstr "Индексът е променен" -#: git-gui.sh:3402 lib/transport.tcl:137 msgid "Push" msgstr "Изтласкване" -#: git-gui.sh:3429 msgid "Initial Commit Message:" msgstr "Първоначално съобщение при подаване:" -#: git-gui.sh:3430 msgid "Amended Commit Message:" msgstr "Поправено съобщение при подаване:" -#: git-gui.sh:3431 msgid "Amended Initial Commit Message:" msgstr "Поправено първоначално съобщение при подаване:" -#: git-gui.sh:3432 msgid "Amended Merge Commit Message:" msgstr "Поправено съобщение при подаване със сливане:" -#: git-gui.sh:3433 msgid "Merge Commit Message:" msgstr "Съобщение при подаване със сливане:" -#: git-gui.sh:3434 msgid "Commit Message:" msgstr "Съобщение при подаване:" -#: git-gui.sh:3493 git-gui.sh:3659 lib/console.tcl:73 msgid "Copy All" msgstr "Копиране на всичко" -#: git-gui.sh:3517 lib/blame.tcl:106 msgid "File:" msgstr "Файл:" -#: git-gui.sh:3565 lib/choose_repository.tcl:1054 msgid "Open" msgstr "Отваряне" -#: git-gui.sh:3647 msgid "Refresh" msgstr "Обновяване" -#: git-gui.sh:3668 msgid "Decrease Font Size" msgstr "По-дребен шрифт" -#: git-gui.sh:3672 msgid "Increase Font Size" msgstr "По-едър шрифт" -#: git-gui.sh:3680 lib/blame.tcl:296 msgid "Encoding" msgstr "Кодиране" -#: git-gui.sh:3691 msgid "Apply/Reverse Hunk" msgstr "Прилагане/връщане на парче" -#: git-gui.sh:3696 msgid "Apply/Reverse Line" msgstr "Прилагане/връщане на ред" -#: git-gui.sh:3702 git-gui.sh:3812 git-gui.sh:3823 msgid "Revert Hunk" msgstr "Връщане на парче" -#: git-gui.sh:3707 git-gui.sh:3819 git-gui.sh:3830 msgid "Revert Line" msgstr "Връщане на ред" -#: git-gui.sh:3712 git-gui.sh:3809 msgid "Undo Last Revert" msgstr "Отмяна на последното връщане" -#: git-gui.sh:3731 msgid "Run Merge Tool" msgstr "Изпълнение на програмата за сливане" -#: git-gui.sh:3736 msgid "Use Remote Version" msgstr "Версия от отдалеченото хранилище" -#: git-gui.sh:3740 msgid "Use Local Version" msgstr "Локална версия" -#: git-gui.sh:3744 msgid "Revert To Base" msgstr "Връщане към родителската версия" -#: git-gui.sh:3762 msgid "Visualize These Changes In The Submodule" msgstr "Визуализиране на промените в подмодула" -#: git-gui.sh:3766 msgid "Visualize Current Branch History In The Submodule" msgstr "Визуализация на историята на текущия клон в историята за подмодула" -#: git-gui.sh:3770 msgid "Visualize All Branch History In The Submodule" msgstr "Визуализация на историята на всички клони в историята за подмодула" -#: git-gui.sh:3775 msgid "Start git gui In The Submodule" msgstr "Стартиране на „git gui“ за подмодула" -#: git-gui.sh:3811 msgid "Unstage Hunk From Commit" msgstr "Изваждане на парчето от подаването" -#: git-gui.sh:3815 msgid "Unstage Lines From Commit" msgstr "Изваждане на редовете от подаването" -#: git-gui.sh:3816 git-gui.sh:3827 msgid "Revert Lines" msgstr "Връщане на редовете" -#: git-gui.sh:3818 msgid "Unstage Line From Commit" msgstr "Изваждане на реда от подаването" -#: git-gui.sh:3822 msgid "Stage Hunk For Commit" msgstr "Добавяне на парчето за подаване" -#: git-gui.sh:3826 msgid "Stage Lines For Commit" msgstr "Добавяне на редовете за подаване" -#: git-gui.sh:3829 msgid "Stage Line For Commit" msgstr "Добавяне на реда за подаване" -#: git-gui.sh:3879 msgid "Initializing..." msgstr "Инициализиране…" -#: lib/about.tcl:26 msgid "git-gui - a graphical user interface for Git." msgstr "git-gui — графичен интерфейс за Git." -#: lib/blame.tcl:74 #, tcl-format msgid "%s (%s): File Viewer" msgstr "%s (%s): Преглед на файлове" -#: lib/blame.tcl:80 msgid "Commit:" msgstr "Подаване:" -#: lib/blame.tcl:282 msgid "Copy Commit" msgstr "Копиране на подаване" -#: lib/blame.tcl:286 msgid "Find Text..." msgstr "Търсене на текст…" -#: lib/blame.tcl:290 msgid "Goto Line..." msgstr "Към ред…" -#: lib/blame.tcl:299 msgid "Do Full Copy Detection" msgstr "Пълно търсене на копиране" -#: lib/blame.tcl:303 msgid "Show History Context" msgstr "Показване на контекста от историята" -#: lib/blame.tcl:306 msgid "Blame Parent Commit" msgstr "Анотиране на родителското подаване" -#: lib/blame.tcl:469 #, tcl-format msgid "Reading %s..." msgstr "Чете се „%s“…" -#: lib/blame.tcl:597 msgid "Loading copy/move tracking annotations..." msgstr "Зареждане на анотациите за проследяване на копирането/преместването…" -#: lib/blame.tcl:614 msgid "lines annotated" msgstr "реда анотирани" -#: lib/blame.tcl:816 msgid "Loading original location annotations..." msgstr "Зареждане на анотациите за първоначалното местоположение…" -#: lib/blame.tcl:819 msgid "Annotation complete." msgstr "Анотирането завърши." -#: lib/blame.tcl:850 msgid "Busy" msgstr "Операцията не е завършила" -#: lib/blame.tcl:851 msgid "Annotation process is already running." msgstr "В момента тече процес на анотиране." -#: lib/blame.tcl:890 msgid "Running thorough copy detection..." msgstr "Изпълнява се цялостен процес на откриване на копиране…" -#: lib/blame.tcl:958 msgid "Loading annotation..." msgstr "Зареждане на анотации…" -#: lib/blame.tcl:1011 msgid "Author:" msgstr "Автор:" -#: lib/blame.tcl:1015 msgid "Committer:" msgstr "Подал:" -#: lib/blame.tcl:1020 msgid "Original File:" msgstr "Първоначален файл:" -#: lib/blame.tcl:1068 msgid "Cannot find HEAD commit:" msgstr "Подаването за връх „HEAD“ не може да се открие:" -#: lib/blame.tcl:1123 msgid "Cannot find parent commit:" msgstr "Родителското подаване не може да се открие" -#: lib/blame.tcl:1138 msgid "Unable to display parent" msgstr "Родителят не може да се покаже" -#: lib/blame.tcl:1139 lib/diff.tcl:334 msgid "Error loading diff:" msgstr "Грешка при зареждане на разлика:" -#: lib/blame.tcl:1280 msgid "Originally By:" msgstr "Първоначално от:" -#: lib/blame.tcl:1286 msgid "In File:" msgstr "Във файл:" -#: lib/blame.tcl:1291 msgid "Copied Or Moved Here By:" msgstr "Копирано или преместено тук от:" -#: lib/branch_checkout.tcl:16 #, tcl-format msgid "%s (%s): Checkout Branch" msgstr "%s (%s): Клон за изтегляне" -#: lib/branch_checkout.tcl:21 msgid "Checkout Branch" msgstr "Клон за изтегляне" -#: lib/branch_checkout.tcl:26 msgid "Checkout" msgstr "Изтегляне" -#: lib/branch_checkout.tcl:30 lib/branch_create.tcl:37 lib/branch_delete.tcl:34 -#: lib/branch_rename.tcl:32 lib/browser.tcl:292 lib/checkout_op.tcl:580 -#: lib/choose_font.tcl:45 lib/merge.tcl:178 lib/option.tcl:127 -#: lib/remote_add.tcl:34 lib/remote_branch_delete.tcl:43 lib/tools_dlg.tcl:41 -#: lib/tools_dlg.tcl:202 lib/tools_dlg.tcl:345 lib/transport.tcl:141 msgid "Cancel" msgstr "Отказване" -#: lib/branch_checkout.tcl:35 lib/browser.tcl:297 lib/tools_dlg.tcl:321 msgid "Revision" msgstr "Версия" -#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:69 lib/option.tcl:310 msgid "Options" msgstr "Опции" -#: lib/branch_checkout.tcl:42 lib/branch_create.tcl:92 msgid "Fetch Tracking Branch" msgstr "Изтегляне на промените от следения клон" -#: lib/branch_checkout.tcl:47 msgid "Detach From Local Branch" msgstr "Изтриване от локалния клон" -#: lib/branch_create.tcl:23 #, tcl-format msgid "%s (%s): Create Branch" msgstr "%s (%s): Създаване на клон" -#: lib/branch_create.tcl:28 msgid "Create New Branch" msgstr "Създаване на нов клон" -#: lib/branch_create.tcl:33 lib/choose_repository.tcl:386 msgid "Create" msgstr "Създаване" -#: lib/branch_create.tcl:42 msgid "Branch Name" msgstr "Име на клона" -#: lib/branch_create.tcl:44 lib/remote_add.tcl:41 lib/tools_dlg.tcl:51 msgid "Name:" msgstr "Име:" -#: lib/branch_create.tcl:57 msgid "Match Tracking Branch Name" msgstr "Съвпадане по името на следения клон" -#: lib/branch_create.tcl:66 msgid "Starting Revision" msgstr "Начална версия" -#: lib/branch_create.tcl:72 msgid "Update Existing Branch:" msgstr "Обновяване на съществуващ клон:" -#: lib/branch_create.tcl:75 msgid "No" msgstr "Не" -#: lib/branch_create.tcl:80 msgid "Fast Forward Only" msgstr "Само тривиално превъртащо сливане" -#: lib/branch_create.tcl:85 lib/checkout_op.tcl:572 msgid "Reset" msgstr "Отначало" -#: lib/branch_create.tcl:97 msgid "Checkout After Creation" msgstr "Преминаване към клона след създаването му" -#: lib/branch_create.tcl:132 msgid "Please select a tracking branch." msgstr "Изберете клон за следени." -#: lib/branch_create.tcl:141 #, tcl-format msgid "Tracking branch %s is not a branch in the remote repository." msgstr "Следящият клон — „%s“, не съществува в отдалеченото хранилище." -#: lib/branch_create.tcl:154 lib/branch_rename.tcl:92 msgid "Please supply a branch name." msgstr "Дайте име на клона." -#: lib/branch_create.tcl:165 lib/branch_rename.tcl:112 #, tcl-format msgid "'%s' is not an acceptable branch name." msgstr "„%s“ не може да се използва за име на клон." -#: lib/branch_delete.tcl:16 #, tcl-format msgid "%s (%s): Delete Branch" msgstr "%s (%s): Изтриване на клон" -#: lib/branch_delete.tcl:21 msgid "Delete Local Branch" msgstr "Изтриване на локален клон" -#: lib/branch_delete.tcl:39 msgid "Local Branches" msgstr "Локални клони" -#: lib/branch_delete.tcl:51 msgid "Delete Only If Merged Into" msgstr "Изтриване, само ако промените са слети и другаде" -#: lib/branch_delete.tcl:53 lib/remote_branch_delete.tcl:120 msgid "Always (Do not perform merge checks)" msgstr "Винаги (без проверка за сливане)" -#: lib/branch_delete.tcl:103 #, tcl-format msgid "The following branches are not completely merged into %s:" msgstr "Не всички промени в клоните са слети в „%s“:" -#: lib/branch_delete.tcl:115 lib/remote_branch_delete.tcl:218 msgid "" "Recovering deleted branches is difficult.\n" "\n" @@ -832,12 +620,10 @@ msgstr "" "\n" "Сигурни ли сте, че искате да триете?" -#: lib/branch_delete.tcl:131 #, tcl-format msgid " - %s:" msgstr " — „%s:“" -#: lib/branch_delete.tcl:141 #, tcl-format msgid "" "Failed to delete branches:\n" @@ -846,100 +632,76 @@ msgstr "" "Неуспешно триене на клони:\n" "%s" -#: lib/branch_rename.tcl:15 #, tcl-format msgid "%s (%s): Rename Branch" msgstr "%s (%s): Преименуване на клон" -#: lib/branch_rename.tcl:23 msgid "Rename Branch" msgstr "Преименуване на клон" -#: lib/branch_rename.tcl:28 msgid "Rename" msgstr "Преименуване" -#: lib/branch_rename.tcl:38 msgid "Branch:" msgstr "Клон:" -#: lib/branch_rename.tcl:46 msgid "New Name:" msgstr "Ново име:" -#: lib/branch_rename.tcl:81 msgid "Please select a branch to rename." msgstr "Изберете клон за преименуване." -#: lib/branch_rename.tcl:102 lib/checkout_op.tcl:202 #, tcl-format msgid "Branch '%s' already exists." msgstr "Клонът „%s“ вече съществува." -#: lib/branch_rename.tcl:123 #, tcl-format msgid "Failed to rename '%s'." msgstr "Неуспешно преименуване на „%s“." -#: lib/browser.tcl:17 msgid "Starting..." msgstr "Стартиране…" -#: lib/browser.tcl:27 #, tcl-format msgid "%s (%s): File Browser" msgstr "%s (%s): Файлов браузър" -#: lib/browser.tcl:132 lib/browser.tcl:149 #, tcl-format msgid "Loading %s..." msgstr "Зареждане на „%s“…" -#: lib/browser.tcl:193 msgid "[Up To Parent]" msgstr "[Към родителя]" -#: lib/browser.tcl:275 #, tcl-format msgid "%s (%s): Browse Branch Files" msgstr "%s (%s): Разглеждане на файловете в клона" -#: lib/browser.tcl:282 msgid "Browse Branch Files" msgstr "Разглеждане на файловете в клона" -#: lib/browser.tcl:288 lib/choose_repository.tcl:401 -#: lib/choose_repository.tcl:488 lib/choose_repository.tcl:497 -#: lib/choose_repository.tcl:1069 msgid "Browse" msgstr "Разглеждане" -#: lib/checkout_op.tcl:85 #, tcl-format msgid "Fetching %s from %s" msgstr "Доставяне на „%s“ от „%s“" -#: lib/checkout_op.tcl:133 #, tcl-format msgid "fatal: Cannot resolve %s" msgstr "фатална грешка: „%s“ не може да се открие" -#: lib/checkout_op.tcl:146 lib/console.tcl:81 lib/database.tcl:30 -#: lib/sshkey.tcl:58 msgid "Close" msgstr "Затваряне" -#: lib/checkout_op.tcl:175 #, tcl-format msgid "Branch '%s' does not exist." msgstr "Клонът „%s“ не съществува." -#: lib/checkout_op.tcl:194 #, tcl-format msgid "Failed to configure simplified git-pull for '%s'." msgstr "Неуспешно настройване на опростен git-pull за „%s“." -#: lib/checkout_op.tcl:229 #, tcl-format msgid "" "Branch '%s' already exists.\n" @@ -952,21 +714,17 @@ msgstr "" "Той не може да се слее тривиално до „%s“.\n" "Необходимо е сливане." -#: lib/checkout_op.tcl:243 #, tcl-format msgid "Merge strategy '%s' not supported." msgstr "Стратегия за сливане „%s“ не се поддържа." -#: lib/checkout_op.tcl:262 #, tcl-format msgid "Failed to update '%s'." msgstr "Неуспешно обновяване на „%s“." -#: lib/checkout_op.tcl:274 msgid "Staging area (index) is already locked." msgstr "Индексът вече е заключен." -#: lib/checkout_op.tcl:289 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -983,31 +741,25 @@ msgstr "" "\n" "Автоматично ще започне нова проверка.\n" -#: lib/checkout_op.tcl:345 #, tcl-format msgid "Updating working directory to '%s'..." msgstr "Работната директория се привежда към „%s“…" -#: lib/checkout_op.tcl:346 msgid "files checked out" msgstr "файла са изтеглени" -#: lib/checkout_op.tcl:377 #, tcl-format msgid "Aborted checkout of '%s' (file level merging is required)." msgstr "" "Преустановяване на изтеглянето на „%s“ (необходимо е пофайлово сливане)." -#: lib/checkout_op.tcl:378 msgid "File level merge required." msgstr "Необходимо е пофайлово сливане." -#: lib/checkout_op.tcl:382 #, tcl-format msgid "Staying on branch '%s'." msgstr "Оставане върху клона „%s“." -#: lib/checkout_op.tcl:453 msgid "" "You are no longer on a local branch.\n" "\n" @@ -1018,31 +770,25 @@ msgstr "" "\n" "Ако искате да сте на клон, създайте базиран на „Това несвързано изтегляне“." -#: lib/checkout_op.tcl:504 lib/checkout_op.tcl:508 #, tcl-format msgid "Checked out '%s'." msgstr "„%s“ е изтеглен." -#: lib/checkout_op.tcl:536 #, tcl-format msgid "Resetting '%s' to '%s' will lose the following commits:" msgstr "" "Зануляването на „%s“ към „%s“ ще доведе до загубването на следните подавания:" -#: lib/checkout_op.tcl:558 msgid "Recovering lost commits may not be easy." msgstr "Възстановяването на загубените подавания може да е трудно." -#: lib/checkout_op.tcl:563 #, tcl-format msgid "Reset '%s'?" msgstr "Зануляване на „%s“?" -#: lib/checkout_op.tcl:568 lib/merge.tcl:170 lib/tools_dlg.tcl:336 msgid "Visualize" msgstr "Визуализация" -#: lib/checkout_op.tcl:636 #, tcl-format msgid "" "Failed to set current branch.\n" @@ -1060,23 +806,18 @@ msgstr "" "Това състояние е аварийно и не трябва да се случва. Програмата „%s“ ще " "преустанови работа." -#: lib/choose_font.tcl:41 msgid "Select" msgstr "Избор" -#: lib/choose_font.tcl:55 msgid "Font Family" msgstr "Шрифт" -#: lib/choose_font.tcl:76 msgid "Font Size" msgstr "Размер" -#: lib/choose_font.tcl:93 msgid "Font Example" msgstr "Мостра" -#: lib/choose_font.tcl:105 msgid "" "This is example text.\n" "If you like this text, it can be your font." @@ -1084,289 +825,137 @@ msgstr "" "Това е примерен текст.\n" "Ако ви харесва как изглежда, изберете шрифта." -#: lib/choose_repository.tcl:45 msgid "Git Gui" msgstr "ГПИ на Git" -#: lib/choose_repository.tcl:104 lib/choose_repository.tcl:391 msgid "Create New Repository" msgstr "Създаване на ново хранилище" -#: lib/choose_repository.tcl:110 msgid "New..." msgstr "Ново…" -#: lib/choose_repository.tcl:117 lib/choose_repository.tcl:475 msgid "Clone Existing Repository" msgstr "Клониране на съществуващо хранилище" -#: lib/choose_repository.tcl:128 msgid "Clone..." msgstr "Клониране…" -#: lib/choose_repository.tcl:135 lib/choose_repository.tcl:1059 msgid "Open Existing Repository" msgstr "Отваряне на съществуващо хранилище" -#: lib/choose_repository.tcl:141 msgid "Open..." msgstr "Отваряне…" -#: lib/choose_repository.tcl:154 msgid "Recent Repositories" msgstr "Скоро ползвани" -#: lib/choose_repository.tcl:164 msgid "Open Recent Repository:" msgstr "Отваряне на хранилище ползвано наскоро:" -#: lib/choose_repository.tcl:328 lib/choose_repository.tcl:335 -#: lib/choose_repository.tcl:342 #, tcl-format msgid "Failed to create repository %s:" msgstr "Неуспешно създаване на хранилището „%s“:" -#: lib/choose_repository.tcl:396 msgid "Directory:" msgstr "Директория:" -#: lib/choose_repository.tcl:426 lib/choose_repository.tcl:552 -#: lib/choose_repository.tcl:1093 msgid "Git Repository" msgstr "Хранилище на Git" -#: lib/choose_repository.tcl:451 #, tcl-format msgid "Directory %s already exists." msgstr "Вече съществува директория „%s“." -#: lib/choose_repository.tcl:455 #, tcl-format msgid "File %s already exists." msgstr "Вече съществува файл „%s“." -#: lib/choose_repository.tcl:470 msgid "Clone" msgstr "Клониране" -#: lib/choose_repository.tcl:483 msgid "Source Location:" msgstr "Адрес на източника:" -#: lib/choose_repository.tcl:492 msgid "Target Directory:" msgstr "Целева директория:" -#: lib/choose_repository.tcl:502 msgid "Clone Type:" msgstr "Вид клониране:" -#: lib/choose_repository.tcl:507 msgid "Standard (Fast, Semi-Redundant, Hardlinks)" msgstr "Стандартно (бързо, частично споделяне на файлове, твърди връзки)" -#: lib/choose_repository.tcl:512 msgid "Full Copy (Slower, Redundant Backup)" msgstr "Пълно (бавно, пълноценно резервно копие)" -#: lib/choose_repository.tcl:517 msgid "Shared (Fastest, Not Recommended, No Backup)" msgstr "Споделено (най-бързо, не се препоръчва, не прави резервно копие)" -#: lib/choose_repository.tcl:524 msgid "Recursively clone submodules too" msgstr "Рекурсивно клониране и на подмодулите" -#: lib/choose_repository.tcl:558 lib/choose_repository.tcl:605 -#: lib/choose_repository.tcl:744 lib/choose_repository.tcl:818 -#: lib/choose_repository.tcl:1099 lib/choose_repository.tcl:1107 #, tcl-format msgid "Not a Git repository: %s" msgstr "Това не е хранилище на Git: %s" -#: lib/choose_repository.tcl:594 +msgid "Hardlinks are unavailable. Falling back to copying." +msgstr "Не се поддържат твърди връзки. Преминава се към копиране." + msgid "Standard only available for local repository." msgstr "Само локални хранилища може да се клонират стандартно" -#: lib/choose_repository.tcl:598 msgid "Shared only available for local repository." msgstr "Само локални хранилища може да се клонират споделено" -#: lib/choose_repository.tcl:613 #, tcl-format msgid "Location %s already exists." msgstr "Местоположението „%s“ вече съществува." -#: lib/choose_repository.tcl:624 -msgid "Failed to configure origin" -msgstr "Неуспешно настройване на хранилището-източник" - -#: lib/choose_repository.tcl:636 -msgid "Counting objects" -msgstr "Преброяване на обекти" - -#: lib/choose_repository.tcl:637 -msgid "buckets" -msgstr "клетки" - -#: lib/choose_repository.tcl:657 -#, tcl-format -msgid "Unable to copy objects/info/alternates: %s" -msgstr "Обектите/Информацията/Синонимите не може да се копират: %s" - -#: lib/choose_repository.tcl:694 -#, tcl-format -msgid "Nothing to clone from %s." -msgstr "Няма какво да се клонира от „%s“." - -#: lib/choose_repository.tcl:696 lib/choose_repository.tcl:916 -#: lib/choose_repository.tcl:928 -msgid "The 'master' branch has not been initialized." -msgstr "Основният клон — „master“ не е инициализиран." - -#: lib/choose_repository.tcl:709 -msgid "Hardlinks are unavailable. Falling back to copying." -msgstr "Не се поддържат твърди връзки. Преминава се към копиране." - -#: lib/choose_repository.tcl:723 #, tcl-format msgid "Cloning from %s" msgstr "Клониране на „%s“" -#: lib/choose_repository.tcl:754 -msgid "Copying objects" -msgstr "Копиране на обекти" - -#: lib/choose_repository.tcl:755 -msgid "KiB" -msgstr "KiB" - -#: lib/choose_repository.tcl:779 -#, tcl-format -msgid "Unable to copy object: %s" -msgstr "Неуспешно копиране на обект: %s" - -#: lib/choose_repository.tcl:791 -msgid "Linking objects" -msgstr "Създаване на връзки към обектите" - -#: lib/choose_repository.tcl:792 -msgid "objects" -msgstr "обекти" - -#: lib/choose_repository.tcl:800 -#, tcl-format -msgid "Unable to hardlink object: %s" -msgstr "Неуспешно създаване на твърда връзка към обект: %s" - -#: lib/choose_repository.tcl:857 -msgid "Cannot fetch branches and objects. See console output for details." -msgstr "" -"Клоните и обектите не може да се изтеглят. За повече информация погледнете " -"изхода на конзолата." - -#: lib/choose_repository.tcl:868 -msgid "Cannot fetch tags. See console output for details." -msgstr "" -"Етикетите не може да се изтеглят. За повече информация погледнете изхода на " -"конзолата." - -#: lib/choose_repository.tcl:892 -msgid "Cannot determine HEAD. See console output for details." -msgstr "" -"Върхът „HEAD“ не може да се определи. За повече информация погледнете изхода " -"на конзолата." - -#: lib/choose_repository.tcl:901 -#, tcl-format -msgid "Unable to cleanup %s" -msgstr "„%s“ не може да се изчисти" - -#: lib/choose_repository.tcl:907 msgid "Clone failed." msgstr "Неуспешно клониране." -#: lib/choose_repository.tcl:914 -msgid "No default branch obtained." -msgstr "Не е получен клон по подразбиране." - -#: lib/choose_repository.tcl:925 -#, tcl-format -msgid "Cannot resolve %s as a commit." -msgstr "Няма подаване отговарящо на „%s“." - -#: lib/choose_repository.tcl:952 -msgid "Creating working directory" -msgstr "Създаване на работната директория" - -#: lib/choose_repository.tcl:953 lib/index.tcl:77 lib/index.tcl:146 -#: lib/index.tcl:220 lib/index.tcl:589 -msgid "files" -msgstr "файлове" - -#: lib/choose_repository.tcl:982 -msgid "Initial file checkout failed." -msgstr "Неуспешно първоначално изтегляне." - -#: lib/choose_repository.tcl:1026 -msgid "Cloning submodules" -msgstr "Клониране на подмодули" - -#: lib/choose_repository.tcl:1041 -msgid "Cannot clone submodules." -msgstr "Подмодулите не може да се клонират." - -#: lib/choose_repository.tcl:1064 msgid "Repository:" msgstr "Хранилище:" -#: lib/choose_repository.tcl:1113 #, tcl-format msgid "Failed to open repository %s:" msgstr "Неуспешно отваряне на хранилището „%s“:" -#: lib/choose_rev.tcl:52 msgid "This Detached Checkout" msgstr "Това несвързано изтегляне" -#: lib/choose_rev.tcl:60 msgid "Revision Expression:" msgstr "Израз за версия:" -#: lib/choose_rev.tcl:72 msgid "Local Branch" msgstr "Локален клон" -#: lib/choose_rev.tcl:77 msgid "Tracking Branch" msgstr "Следящ клон" -#: lib/choose_rev.tcl:82 lib/choose_rev.tcl:544 msgid "Tag" msgstr "Етикет" -#: lib/choose_rev.tcl:321 #, tcl-format msgid "Invalid revision: %s" msgstr "Неправилна версия: %s" -#: lib/choose_rev.tcl:342 msgid "No revision selected." msgstr "Не е избрана версия." -#: lib/choose_rev.tcl:350 msgid "Revision expression is empty." msgstr "Изразът за версия е празен." -#: lib/choose_rev.tcl:537 msgid "Updated" msgstr "Обновен" -#: lib/choose_rev.tcl:565 msgid "URL" msgstr "Адрес" -#: lib/commit.tcl:9 msgid "" "There is nothing to amend.\n" "\n" @@ -1378,7 +967,6 @@ msgstr "" "Ще създадете първоначалното подаване. Преди него няма други подавания, които " "да поправите.\n" -#: lib/commit.tcl:18 msgid "" "Cannot amend while merging.\n" "\n" @@ -1391,24 +979,19 @@ msgstr "" "В момента все още не сте завършили операция по сливане. Не може да поправите " "предишното подаване, освен ако първо не преустановите текущото сливане.\n" -#: lib/commit.tcl:56 msgid "Error loading commit data for amend:" msgstr "Грешка при зареждане на данните от подаване, които да се поправят:" -#: lib/commit.tcl:83 msgid "Unable to obtain your identity:" msgstr "Идентификацията ви не може да се определи:" -#: lib/commit.tcl:88 msgid "Invalid GIT_COMMITTER_IDENT:" msgstr "Неправилно поле „GIT_COMMITTER_IDENT“:" -#: lib/commit.tcl:138 #, tcl-format msgid "warning: Tcl does not support encoding '%s'." msgstr "предупреждение: Tcl не поддържа кодирането „%s“." -#: lib/commit.tcl:158 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -1425,7 +1008,6 @@ msgstr "" "\n" "Автоматично ще започне нова проверка.\n" -#: lib/commit.tcl:182 #, tcl-format msgid "" "Unmerged files cannot be committed.\n" @@ -1438,7 +1020,6 @@ msgstr "" "Във файла „%s“ има конфликти при сливане. За да го подадете, трябва първо да " "коригирате конфликтите и да добавите файла към индекса за подаване.\n" -#: lib/commit.tcl:190 #, tcl-format msgid "" "Unknown file state %s detected.\n" @@ -1449,7 +1030,6 @@ msgstr "" "\n" "Файлът „%s“ не може да се подаде чрез текущата програма.\n" -#: lib/commit.tcl:198 msgid "" "No changes to commit.\n" "\n" @@ -1459,7 +1039,6 @@ msgstr "" "\n" "Трябва да добавите поне един файл към индекса, за да подадете.\n" -#: lib/commit.tcl:224 msgid "" "Please supply a commit message.\n" "\n" @@ -1477,15 +1056,12 @@ msgstr "" "● Втори ред: празен.\n" "● Останалите редове: опишете защо се налага тази промяна.\n" -#: lib/commit.tcl:255 msgid "Calling pre-commit hook..." msgstr "Изпълняване на куката преди подаване…" -#: lib/commit.tcl:270 msgid "Commit declined by pre-commit hook." msgstr "Подаването е отхвърлено от куката преди подаване." -#: lib/commit.tcl:289 msgid "" "You are about to commit on a detached head. This is a potentially dangerous " "thing to do because if you switch to another branch you will lose your " @@ -1501,32 +1077,25 @@ msgstr "" " \n" "Сигурни ли сте, че искате да извършите текущото подаване?" -#: lib/commit.tcl:310 msgid "Calling commit-msg hook..." msgstr "Изпълняване на куката за съобщението при подаване…" -#: lib/commit.tcl:325 msgid "Commit declined by commit-msg hook." msgstr "Подаването е отхвърлено от куката за съобщението при подаване." -#: lib/commit.tcl:338 msgid "Committing changes..." msgstr "Подаване на промените…" -#: lib/commit.tcl:355 msgid "write-tree failed:" msgstr "неуспешно запазване на дървото (write-tree):" -#: lib/commit.tcl:356 lib/commit.tcl:406 lib/commit.tcl:433 msgid "Commit failed." msgstr "Неуспешно подаване." -#: lib/commit.tcl:373 #, tcl-format msgid "Commit %s appears to be corrupt" msgstr "Подаването „%s“ изглежда повредено" -#: lib/commit.tcl:378 msgid "" "No changes to commit.\n" "\n" @@ -1541,83 +1110,63 @@ msgstr "" "\n" "Автоматично ще започне нова проверка.\n" -#: lib/commit.tcl:385 msgid "No changes to commit." msgstr "Няма промени за подаване." -#: lib/commit.tcl:405 msgid "commit-tree failed:" msgstr "неуспешно подаване на дървото (commit-tree):" -#: lib/commit.tcl:432 msgid "update-ref failed:" msgstr "неуспешно обновяване на указателите (update-ref):" -#: lib/commit.tcl:526 #, tcl-format msgid "Created commit %s: %s" msgstr "Успешно подаване %s: %s" -#: lib/console.tcl:59 msgid "Working... please wait..." msgstr "В момента се извършва действие, изчакайте…" -#: lib/console.tcl:186 msgid "Success" msgstr "Успех" -#: lib/console.tcl:200 msgid "Error: Command Failed" msgstr "Грешка: неуспешно изпълнение на команда" -#: lib/database.tcl:42 msgid "Number of loose objects" msgstr "Брой непакетирани обекти" -#: lib/database.tcl:43 msgid "Disk space used by loose objects" msgstr "Дисково пространство заето от непакетирани обекти" -#: lib/database.tcl:44 msgid "Number of packed objects" msgstr "Брой пакетирани обекти" -#: lib/database.tcl:45 msgid "Number of packs" msgstr "Брой пакети" -#: lib/database.tcl:46 msgid "Disk space used by packed objects" msgstr "Дисково пространство заето от пакетирани обекти" -#: lib/database.tcl:47 msgid "Packed objects waiting for pruning" msgstr "Пакетирани обекти за окастряне" -#: lib/database.tcl:48 msgid "Garbage files" msgstr "Файлове за боклука" -#: lib/database.tcl:57 lib/option.tcl:182 lib/option.tcl:197 lib/option.tcl:220 -#: lib/option.tcl:282 #, tcl-format msgid "%s:" msgstr "%s:" -#: lib/database.tcl:66 #, tcl-format msgid "%s (%s): Database Statistics" msgstr "%s (%s): Статистика на базата от данни" -#: lib/database.tcl:72 msgid "Compressing the object database" msgstr "Компресиране на базата с данни за обектите" -#: lib/database.tcl:83 msgid "Verifying the object database with fsck-objects" msgstr "Проверка на базата с данни за обектите с програмата „fsck-objects“" -#: lib/database.tcl:107 #, tcl-format msgid "" "This repository currently has approximately %i loose objects.\n" @@ -1634,12 +1183,10 @@ msgstr "" "\n" "Да се започне ли компресирането?" -#: lib/date.tcl:25 #, tcl-format msgid "Invalid date from Git: %s" msgstr "Неправилни данни от Git: %s" -#: lib/diff.tcl:74 msgid "" "* No differences detected; stage the file to de-list it from Unstaged " "Changes.\n" @@ -1647,16 +1194,13 @@ msgstr "" "● Няма разлики. Добавете файла към индекса, за да се извади от промените " "извън индекса.\n" -#: lib/diff.tcl:75 msgid "* Click to find other files that may have the same state.\n" msgstr "● Натиснете, за да потърсите други файлове в това състояние.\n" -#: lib/diff.tcl:106 #, tcl-format msgid "Loading diff of %s..." msgstr "Зареждане на разликите в „%s“…" -#: lib/diff.tcl:132 msgid "" "LOCAL: deleted\n" "REMOTE:\n" @@ -1664,7 +1208,6 @@ msgstr "" "ЛОКАЛНО: изтрит\n" "ОТДАЛЕЧЕНО:\n" -#: lib/diff.tcl:137 msgid "" "REMOTE: deleted\n" "LOCAL:\n" @@ -1672,32 +1215,25 @@ msgstr "" "ОТДАЛЕЧЕНО: изтрит\n" "ЛОКАЛНО:\n" -#: lib/diff.tcl:144 msgid "LOCAL:\n" msgstr "ЛОКАЛНО:\n" -#: lib/diff.tcl:147 msgid "REMOTE:\n" msgstr "ОТДАЛЕЧЕНО:\n" -#: lib/diff.tcl:209 lib/diff.tcl:333 #, tcl-format msgid "Unable to display %s" msgstr "Файлът „%s“ не може да се покаже" -#: lib/diff.tcl:210 msgid "Error loading file:" msgstr "Грешка при зареждане на файл:" -#: lib/diff.tcl:216 msgid "Git Repository (subproject)" msgstr "Хранилище на Git (подмодул)" -#: lib/diff.tcl:228 msgid "* Binary file (not showing content)." msgstr "● Двоичен файл (съдържанието не се показва)." -#: lib/diff.tcl:233 #, tcl-format msgid "" "* Untracked file is %d bytes.\n" @@ -1706,7 +1242,6 @@ msgstr "" "● Неследеният файл е %d байта.\n" "● Показват се само първите %d байта.\n" -#: lib/diff.tcl:239 #, tcl-format msgid "" "\n" @@ -1717,80 +1252,62 @@ msgstr "" "● Неследеният файл е отрязан дотук от програмата „%s“.\n" "● Използвайте външен редактор, за да видите целия файл.\n" -#: lib/diff.tcl:569 msgid "Failed to unstage selected hunk." msgstr "Избраното парче не може да се извади от индекса." -#: lib/diff.tcl:577 msgid "Failed to revert selected hunk." msgstr "Избраното парче не може да се върне." -#: lib/diff.tcl:580 msgid "Failed to stage selected hunk." msgstr "Избраното парче не може да се добави към индекса." -#: lib/diff.tcl:673 msgid "Failed to unstage selected line." msgstr "Избраният ред не може да се извади от индекса." -#: lib/diff.tcl:682 msgid "Failed to revert selected line." msgstr "Избраният ред не може да се върне." -#: lib/diff.tcl:686 msgid "Failed to stage selected line." msgstr "Избраният ред не може да се добави към индекса." -#: lib/diff.tcl:875 msgid "Failed to undo last revert." msgstr "Неуспешна отмяна на последното връщане." -#: lib/encoding.tcl:443 msgid "Default" msgstr "Стандартното" -#: lib/encoding.tcl:448 #, tcl-format msgid "System (%s)" msgstr "Системното (%s)" -#: lib/encoding.tcl:459 lib/encoding.tcl:465 msgid "Other" msgstr "Друго" -#: lib/error.tcl:20 #, tcl-format msgid "%s: error" msgstr "%s: грешка" -#: lib/error.tcl:36 #, tcl-format msgid "%s: warning" msgstr "%s: предупреждение" -#: lib/error.tcl:80 #, tcl-format msgid "%s hook failed:" msgstr "%s: грешка от куката" -#: lib/error.tcl:96 msgid "You must correct the above errors before committing." msgstr "Преди да можете да подадете, коригирайте горните грешки." -#: lib/error.tcl:116 #, tcl-format msgid "%s (%s): error" msgstr "%s (%s): грешка" -#: lib/index.tcl:6 msgid "Unable to unlock the index." msgstr "Индексът не може да се отключи." -#: lib/index.tcl:30 msgid "Index Error" msgstr "Грешка в индекса" -#: lib/index.tcl:32 msgid "" "Updating the Git index failed. A rescan will be automatically started to " "resynchronize git-gui." @@ -1798,119 +1315,96 @@ msgstr "" "Неуспешно обновяване на индекса на Git. Автоматично ще започне нова проверка " "за синхронизирането на git-gui." -#: lib/index.tcl:43 msgid "Continue" msgstr "Продължаване" -#: lib/index.tcl:46 msgid "Unlock Index" msgstr "Отключване на индекса" -#: lib/index.tcl:326 +msgid "files" +msgstr "файлове" + msgid "Unstaging selected files from commit" msgstr "Изваждане на избраните файлове от подаването" -#: lib/index.tcl:330 #, tcl-format msgid "Unstaging %s from commit" msgstr "Изваждане на „%s“ от подаването" -#: lib/index.tcl:369 msgid "Ready to commit." msgstr "Готовност за подаване." -#: lib/index.tcl:378 msgid "Adding selected files" msgstr "Добавяне на избраните файлове" -#: lib/index.tcl:382 #, tcl-format msgid "Adding %s" msgstr "Добавяне на „%s“" -#: lib/index.tcl:412 #, tcl-format msgid "Stage %d untracked files?" msgstr "Да се добавят ли %d неследени файла към индекса?" -#: lib/index.tcl:420 msgid "Adding all changed files" msgstr "Добавяне на всички променени файлове" -#: lib/index.tcl:503 #, tcl-format msgid "Revert changes in file %s?" msgstr "Да се махнат ли промените във файла „%s“?" -#: lib/index.tcl:508 #, tcl-format msgid "Revert changes in these %i files?" msgstr "Да се махнат ли промените в тези %i файла?" -#: lib/index.tcl:517 msgid "Any unstaged changes will be permanently lost by the revert." msgstr "" "Всички промени, които не са били добавени в индекса, ще се загубят " "безвъзвратно." -#: lib/index.tcl:520 lib/index.tcl:564 msgid "Do Nothing" msgstr "Нищо да не се прави" -#: lib/index.tcl:546 #, tcl-format msgid "Delete untracked file %s?" msgstr "Да се изтрие ли неследеният файл „%s“?" -#: lib/index.tcl:551 #, tcl-format msgid "Delete these %i untracked files?" msgstr "Да се изтрият ли тези %d неследени файла?" -#: lib/index.tcl:561 msgid "Files will be permanently deleted." msgstr "Файловете ще се изтрият окончателно." -#: lib/index.tcl:565 msgid "Delete Files" msgstr "Изтриване на файлове" -#: lib/index.tcl:588 msgid "Deleting" msgstr "Изтриване" -#: lib/index.tcl:667 msgid "Encountered errors deleting files:\n" msgstr "Грешки при изтриване на файловете:\n" -#: lib/index.tcl:676 #, tcl-format msgid "None of the %d selected files could be deleted." msgstr "Никой от избраните %d файла не бе изтрит." -#: lib/index.tcl:681 #, tcl-format msgid "%d of the %d selected files could not be deleted." msgstr "%d от избраните %d файла не бяха изтрити." -#: lib/index.tcl:728 msgid "Reverting selected files" msgstr "Махане на промените в избраните файлове" -#: lib/index.tcl:732 #, tcl-format msgid "Reverting %s" msgstr "Махане на промените в „%s“" -#: lib/line.tcl:17 msgid "Goto Line:" msgstr "Към ред:" -#: lib/line.tcl:23 msgid "Go" msgstr "Към" -#: lib/merge.tcl:13 msgid "" "Cannot merge while amending.\n" "\n" @@ -1921,7 +1415,6 @@ msgstr "" "Трябва да завършите поправянето на текущото подаване, преди да започнете " "сливане.\n" -#: lib/merge.tcl:27 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -1938,7 +1431,6 @@ msgstr "" "Автоматично ще започне нова проверка.\n" "\n" -#: lib/merge.tcl:45 #, tcl-format msgid "" "You are in the middle of a conflicted merge.\n" @@ -1956,7 +1448,6 @@ msgstr "" "завършите текущото сливане чрез подаване. Чак тогава може да започнете ново " "сливане.\n" -#: lib/merge.tcl:55 #, tcl-format msgid "" "You are in the middle of a change.\n" @@ -1973,39 +1464,31 @@ msgstr "" "Трябва да завършите текущото подаване, преди да започнете сливане. Така ще " "можете лесно да преустановите сливането, ако възникне нужда.\n" -#: lib/merge.tcl:108 #, tcl-format msgid "%s of %s" msgstr "%s от общо %s" -#: lib/merge.tcl:126 #, tcl-format msgid "Merging %s and %s..." msgstr "Сливане на „%s“ и „%s“…" -#: lib/merge.tcl:137 msgid "Merge completed successfully." msgstr "Сливането завърши успешно." -#: lib/merge.tcl:139 msgid "Merge failed. Conflict resolution is required." msgstr "Неуспешно сливане — има конфликти за коригиране." -#: lib/merge.tcl:156 #, tcl-format msgid "%s (%s): Merge" msgstr "%s (%s): Сливане" -#: lib/merge.tcl:164 #, tcl-format msgid "Merge Into %s" msgstr "Сливане в „%s“" -#: lib/merge.tcl:183 msgid "Revision To Merge" msgstr "Версия за сливане" -#: lib/merge.tcl:218 msgid "" "Cannot abort while amending.\n" "\n" @@ -2015,7 +1498,6 @@ msgstr "" "\n" "Трябва да завършите поправката на това подаване.\n" -#: lib/merge.tcl:228 msgid "" "Abort merge?\n" "\n" @@ -2029,7 +1511,6 @@ msgstr "" "\n" "Наистина ли да се преустанови сливането?" -#: lib/merge.tcl:234 msgid "" "Reset changes?\n" "\n" @@ -2043,35 +1524,27 @@ msgstr "" "\n" "Наистина ли да се занулят промените?" -#: lib/merge.tcl:246 msgid "Aborting" msgstr "Преустановяване" -#: lib/merge.tcl:247 msgid "files reset" msgstr "файла със занулени промени" -#: lib/merge.tcl:277 msgid "Abort failed." msgstr "Неуспешно преустановяване." -#: lib/merge.tcl:279 msgid "Abort completed. Ready." msgstr "Успешно преустановяване. Готовност за следващо действие." -#: lib/mergetool.tcl:8 msgid "Force resolution to the base version?" msgstr "Да се използва базовата версия" -#: lib/mergetool.tcl:9 msgid "Force resolution to this branch?" msgstr "Да се използва версията от този клон" -#: lib/mergetool.tcl:10 msgid "Force resolution to the other branch?" msgstr "Да се използва версията от другия клон" -#: lib/mergetool.tcl:14 #, tcl-format msgid "" "Note that the diff shows only conflicting changes.\n" @@ -2086,34 +1559,28 @@ msgstr "" "\n" "Тази операция може да се отмени само чрез започване на сливането наново." -#: lib/mergetool.tcl:45 #, tcl-format msgid "File %s seems to have unresolved conflicts, still stage?" msgstr "" "Изглежда, че все още има некоригирани конфликти във файла „%s“. Да се добави " "ли файлът към индекса?" -#: lib/mergetool.tcl:60 #, tcl-format msgid "Adding resolution for %s" msgstr "Добавяне на корекция на конфликтите в „%s“" -#: lib/mergetool.tcl:141 msgid "Cannot resolve deletion or link conflicts using a tool" msgstr "" "Конфликтите при символни връзки или изтриване не може да се коригират с " "външна програма." -#: lib/mergetool.tcl:146 msgid "Conflict file does not exist" msgstr "Файлът, в който е конфликтът, не съществува" -#: lib/mergetool.tcl:246 #, tcl-format msgid "Not a GUI merge tool: '%s'" msgstr "Това не е графична програма за сливане: „%s“" -#: lib/mergetool.tcl:278 #, tcl-format msgid "" "Unable to process square brackets in \"mergetool.%s.cmd\" configuration " @@ -2125,7 +1592,6 @@ msgstr "" "\n" "Махнете ги." -#: lib/mergetool.tcl:289 #, tcl-format msgid "" "Unsupported merge tool '%s'.\n" @@ -2138,11 +1604,9 @@ msgstr "" "За да я използвате, настройте „mergetool.%s.cmd“ както както е обяснено в " "страницата на ръководството за „git-config“." -#: lib/mergetool.tcl:327 msgid "Merge tool is already running, terminate it?" msgstr "Програмата за сливане вече е стартирана. Да се изключи ли?" -#: lib/mergetool.tcl:347 #, tcl-format msgid "" "Error retrieving versions:\n" @@ -2151,7 +1615,6 @@ msgstr "" "Грешка при изтеглянето на версии:\n" "%s" -#: lib/mergetool.tcl:367 #, tcl-format msgid "" "Could not start the merge tool:\n" @@ -2162,277 +1625,211 @@ msgstr "" "\n" "%s" -#: lib/mergetool.tcl:371 msgid "Running merge tool..." msgstr "Стартиране на програмата за сливане…" -#: lib/mergetool.tcl:399 lib/mergetool.tcl:407 msgid "Merge tool failed." msgstr "Грешка в програмата за сливане." -#: lib/option.tcl:11 #, tcl-format msgid "Invalid global encoding '%s'" msgstr "Неправилно глобално кодиране „%s“" -#: lib/option.tcl:19 #, tcl-format msgid "Invalid repo encoding '%s'" msgstr "Неправилно кодиране „%s“ на хранилището" -#: lib/option.tcl:119 msgid "Restore Defaults" msgstr "Стандартни настройки" -#: lib/option.tcl:123 msgid "Save" msgstr "Запазване" -#: lib/option.tcl:133 #, tcl-format msgid "%s Repository" msgstr "Хранилище „%s“" -#: lib/option.tcl:134 msgid "Global (All Repositories)" msgstr "Глобално (за всички хранилища)" -#: lib/option.tcl:140 msgid "User Name" msgstr "Потребителско име" -#: lib/option.tcl:141 msgid "Email Address" msgstr "Адрес на е-поща" -#: lib/option.tcl:143 msgid "Summarize Merge Commits" msgstr "Обобщаване на подаванията при сливане" -#: lib/option.tcl:144 msgid "Merge Verbosity" msgstr "Подробности при сливанията" -#: lib/option.tcl:145 msgid "Show Diffstat After Merge" msgstr "Извеждане на статистика след сливанията" -#: lib/option.tcl:146 msgid "Use Merge Tool" msgstr "Използване на програма за сливане" -#: lib/option.tcl:148 msgid "Trust File Modification Timestamps" msgstr "Доверие във времето на промяна на файловете" -#: lib/option.tcl:149 msgid "Prune Tracking Branches During Fetch" msgstr "Окастряне на следящите клонове при доставяне" -#: lib/option.tcl:150 msgid "Match Tracking Branches" msgstr "Напасване на следящите клонове" -#: lib/option.tcl:151 msgid "Use Textconv For Diffs and Blames" msgstr "Използване на „textconv“ за разликите и анотирането" -#: lib/option.tcl:152 msgid "Blame Copy Only On Changed Files" msgstr "Анотиране на копието само по променените файлове" -#: lib/option.tcl:153 msgid "Maximum Length of Recent Repositories List" msgstr "Максимален брой на списъка „Скоро ползвани“ хранилища" -#: lib/option.tcl:154 msgid "Minimum Letters To Blame Copy On" msgstr "Минимален брой знаци за анотиране на копието" -#: lib/option.tcl:155 msgid "Blame History Context Radius (days)" msgstr "Исторически обхват за анотиране в дни" -#: lib/option.tcl:156 msgid "Number of Diff Context Lines" msgstr "Брой редове за контекста на разликите" -#: lib/option.tcl:157 msgid "Additional Diff Parameters" msgstr "Аргументи към командата за разликите" -#: lib/option.tcl:158 msgid "Commit Message Text Width" msgstr "Широчина на текста на съобщението при подаване" -#: lib/option.tcl:159 msgid "New Branch Name Template" msgstr "Шаблон за името на новите клони" -#: lib/option.tcl:160 msgid "Default File Contents Encoding" msgstr "Кодиране на файловете" -#: lib/option.tcl:161 msgid "Warn before committing to a detached head" msgstr "Предупреждаване при подаване към несвързан указател" -#: lib/option.tcl:162 msgid "Staging of untracked files" msgstr "Добавяне на неследените файлове към индекса" -#: lib/option.tcl:163 msgid "Show untracked files" msgstr "Показване на неследените файлове" -#: lib/option.tcl:164 msgid "Tab spacing" msgstr "Ширина на табулацията" -#: lib/option.tcl:210 msgid "Change" msgstr "Смяна" -#: lib/option.tcl:254 msgid "Spelling Dictionary:" msgstr "Правописен речник:" -#: lib/option.tcl:284 msgid "Change Font" msgstr "Смяна на шрифта" -#: lib/option.tcl:288 #, tcl-format msgid "Choose %s" msgstr "Избор на „%s“" -#: lib/option.tcl:294 msgid "pt." msgstr "тчк." -#: lib/option.tcl:308 msgid "Preferences" msgstr "Настройки" -#: lib/option.tcl:345 msgid "Failed to completely save options:" msgstr "Неуспешно запазване на настройките:" -#: lib/remote_add.tcl:20 #, tcl-format msgid "%s (%s): Add Remote" msgstr "%s (%s): Добавяне на отдалечено хранилище" -#: lib/remote_add.tcl:25 msgid "Add New Remote" msgstr "Добавяне на отдалечено хранилище" -#: lib/remote_add.tcl:30 lib/tools_dlg.tcl:37 msgid "Add" msgstr "Добавяне" -#: lib/remote_add.tcl:39 msgid "Remote Details" msgstr "Данни за отдалеченото хранилище" -#: lib/remote_add.tcl:50 msgid "Location:" msgstr "Местоположение:" -#: lib/remote_add.tcl:60 msgid "Further Action" msgstr "Следващо действие" -#: lib/remote_add.tcl:63 msgid "Fetch Immediately" msgstr "Незабавно доставяне" -#: lib/remote_add.tcl:69 msgid "Initialize Remote Repository and Push" msgstr "Инициализиране на отдалеченото хранилище и изтласкване на промените" -#: lib/remote_add.tcl:75 msgid "Do Nothing Else Now" msgstr "Да не се прави нищо" -#: lib/remote_add.tcl:100 msgid "Please supply a remote name." msgstr "Задайте име за отдалеченото хранилище." -#: lib/remote_add.tcl:113 #, tcl-format msgid "'%s' is not an acceptable remote name." msgstr "Отдалечено хранилище не може да се казва „%s“." -#: lib/remote_add.tcl:124 #, tcl-format msgid "Failed to add remote '%s' of location '%s'." msgstr "Неуспешно добавяне на отдалеченото хранилище „%s“ от адрес „%s“." -#: lib/remote_add.tcl:132 lib/transport.tcl:6 #, tcl-format msgid "fetch %s" msgstr "доставяне на „%s“" -#: lib/remote_add.tcl:133 #, tcl-format msgid "Fetching the %s" msgstr "Доставяне на „%s“" -#: lib/remote_add.tcl:156 #, tcl-format msgid "Do not know how to initialize repository at location '%s'." msgstr "Хранилището с местоположение „%s“ не може да се инициализира." -#: lib/remote_add.tcl:162 lib/transport.tcl:54 lib/transport.tcl:92 -#: lib/transport.tcl:110 #, tcl-format msgid "push %s" msgstr "изтласкване на „%s“" -#: lib/remote_add.tcl:163 #, tcl-format msgid "Setting up the %s (at %s)" msgstr "Добавяне на хранилище „%s“ (с адрес „%s“)" -#: lib/remote_branch_delete.tcl:29 #, tcl-format msgid "%s (%s): Delete Branch Remotely" msgstr "%s (%s): Изтриване на отдалечения клон" -#: lib/remote_branch_delete.tcl:34 msgid "Delete Branch Remotely" msgstr "Изтриване на отдалечения клон" -#: lib/remote_branch_delete.tcl:48 msgid "From Repository" msgstr "От хранилище" -#: lib/remote_branch_delete.tcl:51 lib/transport.tcl:165 msgid "Remote:" msgstr "Отдалечено хранилище:" -#: lib/remote_branch_delete.tcl:72 lib/transport.tcl:187 msgid "Arbitrary Location:" msgstr "Произволно местоположение:" -#: lib/remote_branch_delete.tcl:88 msgid "Branches" msgstr "Клони" -#: lib/remote_branch_delete.tcl:110 msgid "Delete Only If" msgstr "Изтриване, само ако" -#: lib/remote_branch_delete.tcl:112 msgid "Merged Into:" msgstr "Слят в:" -#: lib/remote_branch_delete.tcl:153 msgid "A branch is required for 'Merged Into'." msgstr "За данните „Слят в“ е необходимо да зададете клон." -#: lib/remote_branch_delete.tcl:185 #, tcl-format msgid "" "The following branches are not completely merged into %s:\n" @@ -2443,7 +1840,6 @@ msgstr "" "\n" " ● %s" -#: lib/remote_branch_delete.tcl:190 #, tcl-format msgid "" "One or more of the merge tests failed because you have not fetched the " @@ -2452,140 +1848,107 @@ msgstr "" "Поне една от пробите за сливане е неуспешна, защото не сте доставили всички " "необходими подавания. Пробвайте първо да доставите подаванията от „%s“." -#: lib/remote_branch_delete.tcl:208 msgid "Please select one or more branches to delete." msgstr "Изберете поне един клон за изтриване." -#: lib/remote_branch_delete.tcl:227 #, tcl-format msgid "Deleting branches from %s" msgstr "Изтриване на клони от „%s“" -#: lib/remote_branch_delete.tcl:300 msgid "No repository selected." msgstr "Не е избрано хранилище." -#: lib/remote_branch_delete.tcl:305 #, tcl-format msgid "Scanning %s..." msgstr "Претърсване на „%s“…" -#: lib/remote.tcl:200 msgid "Push to" msgstr "Изтласкване към" -#: lib/remote.tcl:218 msgid "Remove Remote" msgstr "Премахване на отдалечено хранилище" -#: lib/remote.tcl:223 msgid "Prune from" msgstr "Окастряне от" -#: lib/remote.tcl:228 msgid "Fetch from" msgstr "Доставяне от" -#: lib/remote.tcl:249 lib/remote.tcl:253 lib/remote.tcl:258 lib/remote.tcl:264 msgid "All" msgstr "Всички" -#: lib/search.tcl:48 msgid "Find:" msgstr "Търсене:" -#: lib/search.tcl:50 msgid "Next" msgstr "Следваща поява" -#: lib/search.tcl:51 msgid "Prev" msgstr "Предишна поява" -#: lib/search.tcl:52 msgid "RegExp" msgstr "РегИзр" -#: lib/search.tcl:54 msgid "Case" msgstr "Главни/Малки" -#: lib/shortcut.tcl:8 lib/shortcut.tcl:40 lib/shortcut.tcl:72 #, tcl-format msgid "%s (%s): Create Desktop Icon" msgstr "%s (%s): Добавяне на икона на работния плот" -#: lib/shortcut.tcl:24 lib/shortcut.tcl:62 msgid "Cannot write shortcut:" msgstr "Клавишната комбинация не може да се запази:" -#: lib/shortcut.tcl:137 msgid "Cannot write icon:" msgstr "Иконата не може да се запази:" -#: lib/spellcheck.tcl:57 msgid "Unsupported spell checker" msgstr "Тази програма за проверка на правописа не се поддържа" -#: lib/spellcheck.tcl:65 msgid "Spell checking is unavailable" msgstr "Липсва програма за проверка на правописа" -#: lib/spellcheck.tcl:68 msgid "Invalid spell checking configuration" msgstr "Неправилни настройки на проверката на правописа" -#: lib/spellcheck.tcl:70 #, tcl-format msgid "Reverting dictionary to %s." msgstr "Ползване на речник за език „%s“." -#: lib/spellcheck.tcl:73 msgid "Spell checker silently failed on startup" msgstr "Програмата за правопис даже не стартира успешно." -#: lib/spellcheck.tcl:80 msgid "Unrecognized spell checker" msgstr "Непозната програма за проверка на правописа" -#: lib/spellcheck.tcl:186 msgid "No Suggestions" msgstr "Няма предложения" -#: lib/spellcheck.tcl:388 msgid "Unexpected EOF from spell checker" msgstr "Неочакван край на файл от програмата за проверка на правописа" -#: lib/spellcheck.tcl:392 msgid "Spell Checker Failed" msgstr "Грешка в програмата за проверка на правописа" -#: lib/sshkey.tcl:34 msgid "No keys found." msgstr "Не са открити ключове." -#: lib/sshkey.tcl:37 #, tcl-format msgid "Found a public key in: %s" msgstr "Открит е публичен ключ в „%s“" -#: lib/sshkey.tcl:43 msgid "Generate Key" msgstr "Генериране на ключ" -#: lib/sshkey.tcl:61 msgid "Copy To Clipboard" msgstr "Копиране към системния буфер" -#: lib/sshkey.tcl:75 msgid "Your OpenSSH Public Key" msgstr "Публичният ви ключ за OpenSSH" -#: lib/sshkey.tcl:83 msgid "Generating..." msgstr "Генериране…" -#: lib/sshkey.tcl:89 #, tcl-format msgid "" "Could not start ssh-keygen:\n" @@ -2596,81 +1959,63 @@ msgstr "" "\n" "%s" -#: lib/sshkey.tcl:116 msgid "Generation failed." msgstr "Неуспешно генериране." -#: lib/sshkey.tcl:123 msgid "Generation succeeded, but no keys found." msgstr "Генерирането завърши успешно, а не са намерени ключове." -#: lib/sshkey.tcl:126 #, tcl-format msgid "Your key is in: %s" msgstr "Ключът ви е в „%s“" -#: lib/status_bar.tcl:263 #, tcl-format msgid "%s ... %*i of %*i %s (%3i%%)" msgstr "%s… %*i от общо %*i %s (%3i%%)" -#: lib/tools_dlg.tcl:22 #, tcl-format msgid "%s (%s): Add Tool" msgstr "%s (%s): Добавяне на команда" -#: lib/tools_dlg.tcl:28 msgid "Add New Tool Command" msgstr "Добавяне на команда" -#: lib/tools_dlg.tcl:34 msgid "Add globally" msgstr "Глобално добавяне" -#: lib/tools_dlg.tcl:46 msgid "Tool Details" msgstr "Подробности за командата" -#: lib/tools_dlg.tcl:49 msgid "Use '/' separators to create a submenu tree:" msgstr "За създаване на подменюта използвайте знака „/“ за разделител:" -#: lib/tools_dlg.tcl:60 msgid "Command:" msgstr "Команда:" -#: lib/tools_dlg.tcl:71 msgid "Show a dialog before running" msgstr "Преди изпълнение да се извежда диалогов прозорец" -#: lib/tools_dlg.tcl:77 msgid "Ask the user to select a revision (sets $REVISION)" msgstr "Потребителят да укаже версия (задаване на променливата $REVISION)" -#: lib/tools_dlg.tcl:82 msgid "Ask the user for additional arguments (sets $ARGS)" msgstr "" "Потребителят да укаже допълнителни аргументи (задаване на променливата $ARGS)" -#: lib/tools_dlg.tcl:89 msgid "Don't show the command output window" msgstr "Без показване на прозорец с изхода от командата" -#: lib/tools_dlg.tcl:94 msgid "Run only if a diff is selected ($FILENAME not empty)" msgstr "" "Стартиране само след избор на разлика (променливата $FILENAME не е празна)" -#: lib/tools_dlg.tcl:118 msgid "Please supply a name for the tool." msgstr "Задайте име за командата." -#: lib/tools_dlg.tcl:126 #, tcl-format msgid "Tool '%s' already exists." msgstr "Командата „%s“ вече съществува." -#: lib/tools_dlg.tcl:148 #, tcl-format msgid "" "Could not add tool:\n" @@ -2679,154 +2024,121 @@ msgstr "" "Командата не може да се добави:\n" "%s" -#: lib/tools_dlg.tcl:187 #, tcl-format msgid "%s (%s): Remove Tool" msgstr "%s (%s): Премахване на команда" -#: lib/tools_dlg.tcl:193 msgid "Remove Tool Commands" msgstr "Премахване на команди" -#: lib/tools_dlg.tcl:198 msgid "Remove" msgstr "Премахване" -#: lib/tools_dlg.tcl:231 msgid "(Blue denotes repository-local tools)" msgstr "(командите към локалното хранилище са обозначени в синьо)" -#: lib/tools_dlg.tcl:283 #, tcl-format msgid "%s (%s):" msgstr "%s (%s):" -#: lib/tools_dlg.tcl:292 #, tcl-format msgid "Run Command: %s" msgstr "Изпълнение на командата „%s“" -#: lib/tools_dlg.tcl:306 msgid "Arguments" msgstr "Аргументи" -#: lib/tools_dlg.tcl:341 msgid "OK" msgstr "Добре" -#: lib/tools.tcl:76 #, tcl-format msgid "Running %s requires a selected file." msgstr "За изпълнението на „%s“ трябва да изберете файл." -#: lib/tools.tcl:92 #, tcl-format msgid "Are you sure you want to run %1$s on file \"%2$s\"?" msgstr "Сигурни ли сте, че искате да изпълните „%1$s“ върху файла „%2$s“?" -#: lib/tools.tcl:96 #, tcl-format msgid "Are you sure you want to run %s?" msgstr "Сигурни ли сте, че искате да изпълните „%s“?" -#: lib/tools.tcl:118 #, tcl-format msgid "Tool: %s" msgstr "Команда: %s" -#: lib/tools.tcl:119 #, tcl-format msgid "Running: %s" msgstr "Изпълнение: %s" -#: lib/tools.tcl:158 #, tcl-format msgid "Tool completed successfully: %s" msgstr "Командата завърши успешно: %s" -#: lib/tools.tcl:160 #, tcl-format msgid "Tool failed: %s" msgstr "Командата върна грешка: %s" -#: lib/transport.tcl:7 #, tcl-format msgid "Fetching new changes from %s" msgstr "Доставяне на промените от „%s“" -#: lib/transport.tcl:18 #, tcl-format msgid "remote prune %s" msgstr "окастряне на следящите клони към „%s“" -#: lib/transport.tcl:19 #, tcl-format msgid "Pruning tracking branches deleted from %s" msgstr "Окастряне на следящите клони на изтритите клони от „%s“" -#: lib/transport.tcl:25 msgid "fetch all remotes" msgstr "доставяне от всички отдалечени" -#: lib/transport.tcl:26 msgid "Fetching new changes from all remotes" msgstr "Доставяне на промените от всички отдалечени хранилища" -#: lib/transport.tcl:40 msgid "remote prune all remotes" msgstr "окастряне на следящите изтрити" -#: lib/transport.tcl:41 msgid "Pruning tracking branches deleted from all remotes" msgstr "" "Окастряне на следящите клони на изтритите клони от всички отдалечени " "хранилища" -#: lib/transport.tcl:55 #, tcl-format msgid "Pushing changes to %s" msgstr "Изтласкване на промените към „%s“" -#: lib/transport.tcl:93 #, tcl-format msgid "Mirroring to %s" msgstr "Изтласкване на всичко към „%s“" -#: lib/transport.tcl:111 #, tcl-format msgid "Pushing %s %s to %s" msgstr "Изтласкване на %s „%s“ към „%s“" -#: lib/transport.tcl:132 msgid "Push Branches" msgstr "Клони за изтласкване" -#: lib/transport.tcl:147 msgid "Source Branches" msgstr "Клони-източници" -#: lib/transport.tcl:162 msgid "Destination Repository" msgstr "Целево хранилище" -#: lib/transport.tcl:205 msgid "Transfer Options" msgstr "Настройки при пренасянето" -#: lib/transport.tcl:207 msgid "Force overwrite existing branch (may discard changes)" msgstr "" "Изрично презаписване на съществуващ клон (някои промени може да се загубят)" -#: lib/transport.tcl:211 msgid "Use thin pack (for slow network connections)" msgstr "Максимална компресия (за бавни мрежови връзки)" -#: lib/transport.tcl:215 msgid "Include tags" msgstr "Включване на етикетите" -#: lib/transport.tcl:229 #, tcl-format msgid "%s (%s): Push" msgstr "%s (%s): Изтласкване" diff --git a/git-gui/windows/git-gui.sh b/git-gui/windows/git-gui.sh index b1845c5055..38debe376c 100755 --- a/git-gui/windows/git-gui.sh +++ b/git-gui/windows/git-gui.sh @@ -13,13 +13,5 @@ if { $argc >=2 && [lindex $argv 0] == "--working-dir" } { incr argc -2 } -set basedir [file dirname \ - [file dirname \ - [file dirname [info script]]]] -set bindir [file join $basedir bin] -set bindir "$bindir;[file join $basedir mingw bin]" -regsub -all ";" $bindir "\\;" bindir -set env(PATH) "$bindir;$env(PATH)" -unset bindir - -source [file join [file dirname [info script]] git-gui.tcl] +set thisdir [file normalize [file dirname [info script]]] +source [file join $thisdir git-gui.tcl] @@ -371,7 +371,7 @@ static int handle_alias(struct strvec *args) alias_command = args->v[0]; alias_string = alias_lookup(alias_command); if (alias_string) { - if (args->nr > 1 && !strcmp(args->v[1], "-h")) + if (args->nr == 2 && !strcmp(args->v[1], "-h")) fprintf_ln(stderr, _("'%s' is aliased to '%s'"), alias_command, alias_string); if (alias_string[0] == '!') { @@ -2332,7 +2332,7 @@ int http_get_file(const char *url, const char *filename, ret = http_request_reauth(url, result, HTTP_REQUEST_FILE, options); fclose(result); - if (ret == HTTP_OK && finalize_object_file(tmpfile.buf, filename)) + if (ret == HTTP_OK && finalize_object_file(the_repository, tmpfile.buf, filename)) ret = HTTP_ERROR; cleanup: strbuf_release(&tmpfile); @@ -2816,7 +2816,7 @@ int finish_http_object_request(struct http_object_request *freq) return -1; } odb_loose_path(the_repository->objects->sources, &filename, &freq->oid); - freq->rename = finalize_object_file(freq->tmpfile.buf, filename.buf); + freq->rename = finalize_object_file(the_repository, freq->tmpfile.buf, filename.buf); strbuf_release(&filename); return freq->rename; @@ -166,7 +166,8 @@ errout: return -1; } -static int write_one_object(struct repository *repo, const struct object_id *oid, +static int write_one_object(struct odb_source *source, + const struct object_id *oid, const struct object_id *compat_oid) { struct lock_file lock; @@ -174,7 +175,7 @@ static int write_one_object(struct repository *repo, const struct object_id *oid struct stat st; struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT; - repo_common_path_replace(repo, &path, "objects/loose-object-idx"); + strbuf_addf(&path, "%s/loose-object-idx", source->path); hold_lock_file_for_update_timeout(&lock, path.buf, LOCK_DIE_ON_ERROR, -1); fd = open(path.buf, O_WRONLY | O_CREAT | O_APPEND, 0666); @@ -190,7 +191,7 @@ static int write_one_object(struct repository *repo, const struct object_id *oid goto errout; if (close(fd)) goto errout; - adjust_shared_perm(repo, path.buf); + adjust_shared_perm(source->odb->repo, path.buf); rollback_lock_file(&lock); strbuf_release(&buf); strbuf_release(&path); @@ -204,17 +205,18 @@ errout: return -1; } -int repo_add_loose_object_map(struct repository *repo, const struct object_id *oid, +int repo_add_loose_object_map(struct odb_source *source, + const struct object_id *oid, const struct object_id *compat_oid) { int inserted = 0; - if (!should_use_loose_object_map(repo)) + if (!should_use_loose_object_map(source->odb->repo)) return 0; - inserted = insert_loose_map(repo->objects->sources, oid, compat_oid); + inserted = insert_loose_map(source, oid, compat_oid); if (inserted) - return write_one_object(repo, oid, compat_oid); + return write_one_object(source, oid, compat_oid); return 0; } @@ -4,6 +4,7 @@ #include "khash.h" struct repository; +struct odb_source; struct loose_object_map { kh_oid_map_t *to_compat; @@ -16,7 +17,8 @@ int repo_loose_object_map_oid(struct repository *repo, const struct object_id *src, const struct git_hash_algo *dest_algo, struct object_id *dest); -int repo_add_loose_object_map(struct repository *repo, const struct object_id *oid, +int repo_add_loose_object_map(struct odb_source *source, + const struct object_id *oid, const struct object_id *compat_oid); int repo_read_loose_object_map(struct repository *repo); int repo_write_loose_object_map(struct repository *repo); diff --git a/match-trees.c b/match-trees.c index 5a8a5c39b0..4216933d06 100644 --- a/match-trees.c +++ b/match-trees.c @@ -246,7 +246,7 @@ static int splice_tree(struct repository *r, rewrite_with = oid2; } hashcpy(rewrite_here, rewrite_with->hash, r->hash_algo); - status = write_object_file(buf, sz, OBJ_TREE, result); + status = odb_write_object(r->objects, buf, sz, OBJ_TREE, result); free(buf); return status; } diff --git a/merge-ort.c b/merge-ort.c index 86896ff11b..cd0cb4d1f0 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -2216,8 +2216,8 @@ static int handle_content_merge(struct merge_options *opt, } if (!ret && record_object && - write_object_file(result_buf.ptr, result_buf.size, - OBJ_BLOB, &result->oid)) { + odb_write_object(the_repository->objects, result_buf.ptr, result_buf.size, + OBJ_BLOB, &result->oid)) { path_msg(opt, ERROR_OBJECT_WRITE_FAILED, 0, pathnames[0], pathnames[1], pathnames[2], NULL, _("error: unable to add %s to database"), path); @@ -3772,7 +3772,8 @@ static int write_tree(struct object_id *result_oid, } /* Write this object file out, and record in result_oid */ - if (write_object_file(buf.buf, buf.len, OBJ_TREE, result_oid)) + if (odb_write_object(the_repository->objects, buf.buf, + buf.len, OBJ_TREE, result_oid)) ret = -1; strbuf_release(&buf); return ret; diff --git a/midx-write.c b/midx-write.c index c1ae62d354..a0aceab5e0 100644 --- a/midx-write.c +++ b/midx-write.c @@ -667,7 +667,7 @@ static void write_midx_reverse_index(struct write_midx_context *ctx, tmp_file = write_rev_file_order(ctx->repo, NULL, ctx->pack_order, ctx->entries_nr, midx_hash, WRITE_REV); - if (finalize_object_file(tmp_file, buf.buf)) + if (finalize_object_file(ctx->repo, tmp_file, buf.buf)) die(_("cannot store reverse index file")); strbuf_release(&buf); diff --git a/notes-cache.c b/notes-cache.c index dd56feed6e..bf5bb1f6c1 100644 --- a/notes-cache.c +++ b/notes-cache.c @@ -98,7 +98,8 @@ int notes_cache_put(struct notes_cache *c, struct object_id *key_oid, { struct object_id value_oid; - if (write_object_file(data, size, OBJ_BLOB, &value_oid) < 0) + if (odb_write_object(the_repository->objects, data, + size, OBJ_BLOB, &value_oid) < 0) return -1; return add_note(&c->tree, key_oid, &value_oid, NULL); } @@ -682,7 +682,8 @@ static int tree_write_stack_finish_subtree(struct tree_write_stack *tws) ret = tree_write_stack_finish_subtree(n); if (ret) return ret; - ret = write_object_file(n->buf.buf, n->buf.len, OBJ_TREE, &s); + ret = odb_write_object(the_repository->objects, n->buf.buf, + n->buf.len, OBJ_TREE, &s); if (ret) return ret; strbuf_release(&n->buf); @@ -847,7 +848,8 @@ int combine_notes_concatenate(struct object_id *cur_oid, free(new_msg); /* create a new blob object from buf */ - ret = write_object_file(buf, buf_len, OBJ_BLOB, cur_oid); + ret = odb_write_object(the_repository->objects, buf, + buf_len, OBJ_BLOB, cur_oid); free(buf); return ret; } @@ -927,7 +929,8 @@ int combine_notes_cat_sort_uniq(struct object_id *cur_oid, string_list_join_lines_helper, &buf)) goto out; - ret = write_object_file(buf.buf, buf.len, OBJ_BLOB, cur_oid); + ret = odb_write_object(the_repository->objects, buf.buf, + buf.len, OBJ_BLOB, cur_oid); out: strbuf_release(&buf); @@ -1215,7 +1218,8 @@ int write_notes_tree(struct notes_tree *t, struct object_id *result) ret = for_each_note(t, flags, write_each_note, &cb_data) || write_each_non_note_until(NULL, &cb_data) || tree_write_stack_finish_subtree(&root) || - write_object_file(root.buf.buf, root.buf.len, OBJ_TREE, result); + odb_write_object(the_repository->objects, root.buf.buf, + root.buf.len, OBJ_TREE, result); strbuf_release(&root.buf); return ret; } diff --git a/object-file.c b/object-file.c index 3d674d1093..2bc36ab3ee 100644 --- a/object-file.c +++ b/object-file.c @@ -8,7 +8,6 @@ */ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "bulk-checkin.h" @@ -26,6 +25,7 @@ #include "pack.h" #include "packfile.h" #include "path.h" +#include "read-cache-ll.h" #include "setup.h" #include "streaming.h" @@ -42,10 +42,11 @@ static int get_conv_flags(unsigned flags) return 0; } -static void fill_loose_path(struct strbuf *buf, const struct object_id *oid) +static void fill_loose_path(struct strbuf *buf, + const struct object_id *oid, + const struct git_hash_algo *algop) { - int i; - for (i = 0; i < the_hash_algo->rawsz; i++) { + for (size_t i = 0; i < algop->rawsz; i++) { static char hex[] = "0123456789abcdef"; unsigned int val = oid->hash[i]; strbuf_addch(buf, hex[val >> 4]); @@ -62,7 +63,7 @@ const char *odb_loose_path(struct odb_source *source, strbuf_reset(buf); strbuf_addstr(buf, source->path); strbuf_addch(buf, '/'); - fill_loose_path(buf, oid); + fill_loose_path(buf, oid, source->odb->repo->hash_algo); return buf->buf; } @@ -88,46 +89,19 @@ int check_and_freshen_file(const char *fn, int freshen) return 1; } -static int check_and_freshen_odb(struct odb_source *source, - const struct object_id *oid, - int freshen) +static int check_and_freshen_source(struct odb_source *source, + const struct object_id *oid, + int freshen) { static struct strbuf path = STRBUF_INIT; odb_loose_path(source, &path, oid); return check_and_freshen_file(path.buf, freshen); } -static int check_and_freshen_local(const struct object_id *oid, int freshen) +int has_loose_object(struct odb_source *source, + const struct object_id *oid) { - return check_and_freshen_odb(the_repository->objects->sources, oid, freshen); -} - -static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen) -{ - struct odb_source *source; - - odb_prepare_alternates(the_repository->objects); - for (source = the_repository->objects->sources->next; source; source = source->next) { - if (check_and_freshen_odb(source, oid, freshen)) - return 1; - } - return 0; -} - -static int check_and_freshen(const struct object_id *oid, int freshen) -{ - return check_and_freshen_local(oid, freshen) || - check_and_freshen_nonlocal(oid, freshen); -} - -int has_loose_object_nonlocal(const struct object_id *oid) -{ - return check_and_freshen_nonlocal(oid, 0); -} - -int has_loose_object(const struct object_id *oid) -{ - return check_and_freshen(oid, 0); + return check_and_freshen_source(source, oid, 0); } int format_object_header(char *str, size_t size, enum object_type type, @@ -327,9 +301,8 @@ static void *unpack_loose_rest(git_zstream *stream, void *buffer, unsigned long size, const struct object_id *oid) { - int bytes = strlen(buffer) + 1; + size_t bytes = strlen(buffer) + 1, n; unsigned char *buf = xmallocz(size); - unsigned long n; int status = Z_OK; n = stream->total_out - bytes; @@ -448,7 +421,7 @@ int loose_object_info(struct repository *r, enum object_type type_scratch; if (oi->delta_base_oid) - oidclr(oi->delta_base_oid, the_repository->hash_algo); + oidclr(oi->delta_base_oid, r->hash_algo); /* * If we don't care about type or size, then we don't @@ -596,7 +569,7 @@ static int check_collision(const char *source, const char *dest) goto out; } - if (sz_a < sizeof(buf_source)) + if ((size_t) sz_a < sizeof(buf_source)) break; } @@ -611,12 +584,14 @@ out: /* * Move the just written object into its final resting place. */ -int finalize_object_file(const char *tmpfile, const char *filename) +int finalize_object_file(struct repository *repo, + const char *tmpfile, const char *filename) { - return finalize_object_file_flags(tmpfile, filename, 0); + return finalize_object_file_flags(repo, tmpfile, filename, 0); } -int finalize_object_file_flags(const char *tmpfile, const char *filename, +int finalize_object_file_flags(struct repository *repo, + const char *tmpfile, const char *filename, enum finalize_object_file_flags flags) { unsigned retries = 0; @@ -676,7 +651,7 @@ retry: } out: - if (adjust_shared_perm(the_repository, filename)) + if (adjust_shared_perm(repo, filename)) return error(_("unable to set permission to '%s'"), filename); return 0; } @@ -692,9 +667,10 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf, } /* Finalize a file on disk, and close it. */ -static void close_loose_object(int fd, const char *filename) +static void close_loose_object(struct odb_source *source, + int fd, const char *filename) { - if (the_repository->objects->sources->will_destroy) + if (source->will_destroy) goto out; if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT)) @@ -726,7 +702,8 @@ static inline int directory_size(const char *filename) * We want to avoid cross-directory filename renames, because those * can have problems on various filesystems (FAT, NFS, Coda). */ -static int create_tmpfile(struct strbuf *tmp, const char *filename) +static int create_tmpfile(struct repository *repo, + struct strbuf *tmp, const char *filename) { int fd, dirlen = directory_size(filename); @@ -745,7 +722,7 @@ static int create_tmpfile(struct strbuf *tmp, const char *filename) strbuf_add(tmp, filename, dirlen - 1); if (mkdir(tmp->buf, 0777) && errno != EEXIST) return -1; - if (adjust_shared_perm(the_repository, tmp->buf)) + if (adjust_shared_perm(repo, tmp->buf)) return -1; /* Try again */ @@ -766,26 +743,26 @@ static int create_tmpfile(struct strbuf *tmp, const char *filename) * Returns a "fd", which should later be provided to * end_loose_object_common(). */ -static int start_loose_object_common(struct strbuf *tmp_file, +static int start_loose_object_common(struct odb_source *source, + struct strbuf *tmp_file, const char *filename, unsigned flags, git_zstream *stream, unsigned char *buf, size_t buflen, struct git_hash_ctx *c, struct git_hash_ctx *compat_c, char *hdr, int hdrlen) { - struct repository *repo = the_repository; - const struct git_hash_algo *algo = repo->hash_algo; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *algo = source->odb->repo->hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; int fd; - fd = create_tmpfile(tmp_file, filename); + fd = create_tmpfile(source->odb->repo, tmp_file, filename); if (fd < 0) { - if (flags & WRITE_OBJECT_FILE_SILENT) + if (flags & WRITE_OBJECT_SILENT) return -1; else if (errno == EACCES) return error(_("insufficient permission for adding " "an object to repository database %s"), - repo_get_object_directory(the_repository)); + source->path); else return error_errno( _("unable to create temporary file")); @@ -815,14 +792,14 @@ static int start_loose_object_common(struct strbuf *tmp_file, * Common steps for the inner git_deflate() loop for writing loose * objects. Returns what git_deflate() returns. */ -static int write_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx *compat_c, +static int write_loose_object_common(struct odb_source *source, + struct git_hash_ctx *c, struct git_hash_ctx *compat_c, git_zstream *stream, const int flush, unsigned char *in0, const int fd, unsigned char *compressed, const size_t compressed_len) { - struct repository *repo = the_repository; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; int ret; ret = git_deflate(stream, flush ? Z_FINISH : 0); @@ -843,12 +820,12 @@ static int write_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx * - End the compression of zlib stream. * - Get the calculated oid to "oid". */ -static int end_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx *compat_c, +static int end_loose_object_common(struct odb_source *source, + struct git_hash_ctx *c, struct git_hash_ctx *compat_c, git_zstream *stream, struct object_id *oid, struct object_id *compat_oid) { - struct repository *repo = the_repository; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; int ret; ret = git_deflate_end_gently(stream); @@ -861,7 +838,8 @@ static int end_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx * return Z_OK; } -static int write_loose_object(const struct object_id *oid, char *hdr, +static int write_loose_object(struct odb_source *source, + const struct object_id *oid, char *hdr, int hdrlen, const void *buf, unsigned long len, time_t mtime, unsigned flags) { @@ -876,9 +854,9 @@ static int write_loose_object(const struct object_id *oid, char *hdr, if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT)) prepare_loose_object_bulk_checkin(); - odb_loose_path(the_repository->objects->sources, &filename, oid); + odb_loose_path(source, &filename, oid); - fd = start_loose_object_common(&tmp_file, filename.buf, flags, + fd = start_loose_object_common(source, &tmp_file, filename.buf, flags, &stream, compressed, sizeof(compressed), &c, NULL, hdr, hdrlen); if (fd < 0) @@ -890,14 +868,14 @@ static int write_loose_object(const struct object_id *oid, char *hdr, do { unsigned char *in0 = stream.next_in; - ret = write_loose_object_common(&c, NULL, &stream, 1, in0, fd, + ret = write_loose_object_common(source, &c, NULL, &stream, 1, in0, fd, compressed, sizeof(compressed)); } while (ret == Z_OK); if (ret != Z_STREAM_END) die(_("unable to deflate new object %s (%d)"), oid_to_hex(oid), ret); - ret = end_loose_object_common(&c, NULL, &stream, ¶no_oid, NULL); + ret = end_loose_object_common(source, &c, NULL, &stream, ¶no_oid, NULL); if (ret != Z_OK) die(_("deflateEnd on object %s failed (%d)"), oid_to_hex(oid), ret); @@ -905,30 +883,36 @@ static int write_loose_object(const struct object_id *oid, char *hdr, die(_("confused by unstable object source data for %s"), oid_to_hex(oid)); - close_loose_object(fd, tmp_file.buf); + close_loose_object(source, fd, tmp_file.buf); if (mtime) { struct utimbuf utb; utb.actime = mtime; utb.modtime = mtime; if (utime(tmp_file.buf, &utb) < 0 && - !(flags & WRITE_OBJECT_FILE_SILENT)) + !(flags & WRITE_OBJECT_SILENT)) warning_errno(_("failed utime() on %s"), tmp_file.buf); } - return finalize_object_file_flags(tmp_file.buf, filename.buf, + return finalize_object_file_flags(source->odb->repo, tmp_file.buf, filename.buf, FOF_SKIP_COLLISION_CHECK); } -static int freshen_loose_object(const struct object_id *oid) +static int freshen_loose_object(struct object_database *odb, + const struct object_id *oid) { - return check_and_freshen(oid, 1); + odb_prepare_alternates(odb); + for (struct odb_source *source = odb->sources; source; source = source->next) + if (check_and_freshen_source(source, oid, 1)) + return 1; + return 0; } -static int freshen_packed_object(const struct object_id *oid) +static int freshen_packed_object(struct object_database *odb, + const struct object_id *oid) { struct pack_entry e; - if (!find_pack_entry(the_repository, oid, &e)) + if (!find_pack_entry(odb->repo, oid, &e)) return 0; if (e.p->is_cruft) return 0; @@ -940,10 +924,11 @@ static int freshen_packed_object(const struct object_id *oid) return 1; } -int stream_loose_object(struct input_stream *in_stream, size_t len, +int stream_loose_object(struct odb_source *source, + struct input_stream *in_stream, size_t len, struct object_id *oid) { - const struct git_hash_algo *compat = the_repository->compat_hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; struct object_id compat_oid; int fd, ret, err = 0, flush = 0; unsigned char compressed[4096]; @@ -959,7 +944,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, prepare_loose_object_bulk_checkin(); /* Since oid is not determined, save tmp file to odb path. */ - strbuf_addf(&filename, "%s/", repo_get_object_directory(the_repository)); + strbuf_addf(&filename, "%s/", source->path); hdrlen = format_object_header(hdr, sizeof(hdr), OBJ_BLOB, len); /* @@ -970,7 +955,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, * - Setup zlib stream for compression. * - Start to feed header to zlib stream. */ - fd = start_loose_object_common(&tmp_file, filename.buf, 0, + fd = start_loose_object_common(source, &tmp_file, filename.buf, 0, &stream, compressed, sizeof(compressed), &c, &compat_c, hdr, hdrlen); if (fd < 0) { @@ -990,7 +975,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, if (in_stream->is_finished) flush = 1; } - ret = write_loose_object_common(&c, &compat_c, &stream, flush, in0, fd, + ret = write_loose_object_common(source, &c, &compat_c, &stream, flush, in0, fd, compressed, sizeof(compressed)); /* * Unlike write_loose_object(), we do not have the entire @@ -1013,17 +998,18 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, */ if (ret != Z_STREAM_END) die(_("unable to stream deflate new object (%d)"), ret); - ret = end_loose_object_common(&c, &compat_c, &stream, oid, &compat_oid); + ret = end_loose_object_common(source, &c, &compat_c, &stream, oid, &compat_oid); if (ret != Z_OK) die(_("deflateEnd on stream object failed (%d)"), ret); - close_loose_object(fd, tmp_file.buf); + close_loose_object(source, fd, tmp_file.buf); - if (freshen_packed_object(oid) || freshen_loose_object(oid)) { + if (freshen_packed_object(source->odb, oid) || + freshen_loose_object(source->odb, oid)) { unlink_or_warn(tmp_file.buf); goto cleanup; } - odb_loose_path(the_repository->objects->sources, &filename, oid); + odb_loose_path(source, &filename, oid); /* We finally know the object path, and create the missing dir. */ dirlen = directory_size(filename.buf); @@ -1031,7 +1017,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, struct strbuf dir = STRBUF_INIT; strbuf_add(&dir, filename.buf, dirlen); - if (safe_create_dir_in_gitdir(the_repository, dir.buf) && + if (safe_create_dir_in_gitdir(source->odb->repo, dir.buf) && errno != EEXIST) { err = error_errno(_("unable to create directory %s"), dir.buf); strbuf_release(&dir); @@ -1040,23 +1026,23 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, strbuf_release(&dir); } - err = finalize_object_file_flags(tmp_file.buf, filename.buf, + err = finalize_object_file_flags(source->odb->repo, tmp_file.buf, filename.buf, FOF_SKIP_COLLISION_CHECK); if (!err && compat) - err = repo_add_loose_object_map(the_repository, oid, &compat_oid); + err = repo_add_loose_object_map(source, oid, &compat_oid); cleanup: strbuf_release(&tmp_file); strbuf_release(&filename); return err; } -int write_object_file_flags(const void *buf, unsigned long len, - enum object_type type, struct object_id *oid, - struct object_id *compat_oid_in, unsigned flags) +int write_object_file(struct odb_source *source, + const void *buf, unsigned long len, + enum object_type type, struct object_id *oid, + struct object_id *compat_oid_in, unsigned flags) { - struct repository *repo = the_repository; - const struct git_hash_algo *algo = repo->hash_algo; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *algo = source->odb->repo->hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; struct object_id compat_oid; char hdr[MAX_HEADER_LEN]; int hdrlen = sizeof(hdr); @@ -1069,7 +1055,7 @@ int write_object_file_flags(const void *buf, unsigned long len, hash_object_file(compat, buf, len, type, &compat_oid); else { struct strbuf converted = STRBUF_INIT; - convert_object_file(the_repository, &converted, algo, compat, + convert_object_file(source->odb->repo, &converted, algo, compat, buf, len, type, 0); hash_object_file(compat, converted.buf, converted.len, type, &compat_oid); @@ -1081,19 +1067,20 @@ int write_object_file_flags(const void *buf, unsigned long len, * it out into .git/objects/??/?{38} file. */ write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen); - if (freshen_packed_object(oid) || freshen_loose_object(oid)) + if (freshen_packed_object(source->odb, oid) || + freshen_loose_object(source->odb, oid)) return 0; - if (write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags)) + if (write_loose_object(source, oid, hdr, hdrlen, buf, len, 0, flags)) return -1; if (compat) - return repo_add_loose_object_map(repo, oid, &compat_oid); + return repo_add_loose_object_map(source, oid, &compat_oid); return 0; } -int force_object_loose(const struct object_id *oid, time_t mtime) +int force_object_loose(struct odb_source *source, + const struct object_id *oid, time_t mtime) { - struct repository *repo = the_repository; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; void *buf; unsigned long len; struct object_info oi = OBJECT_INFO_INIT; @@ -1103,22 +1090,24 @@ int force_object_loose(const struct object_id *oid, time_t mtime) int hdrlen; int ret; - if (has_loose_object(oid)) - return 0; + for (struct odb_source *s = source->odb->sources; s; s = s->next) + if (has_loose_object(s, oid)) + return 0; + oi.typep = &type; oi.sizep = &len; oi.contentp = &buf; - if (odb_read_object_info_extended(the_repository->objects, oid, &oi, 0)) + if (odb_read_object_info_extended(source->odb, oid, &oi, 0)) return error(_("cannot read object for %s"), oid_to_hex(oid)); if (compat) { - if (repo_oid_to_algop(repo, oid, compat, &compat_oid)) + if (repo_oid_to_algop(source->odb->repo, oid, compat, &compat_oid)) return error(_("cannot map object %s to %s"), oid_to_hex(oid), compat->name); } hdrlen = format_object_header(hdr, sizeof(hdr), type, len); - ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0); + ret = write_loose_object(source, oid, hdr, hdrlen, buf, len, mtime, 0); if (!ret && compat) - ret = repo_add_loose_object_map(the_repository, oid, &compat_oid); + ret = repo_add_loose_object_map(source, oid, &compat_oid); free(buf); return ret; @@ -1168,15 +1157,15 @@ static int index_mem(struct index_state *istate, opts.strict = 1; opts.error_func = hash_format_check_report; - if (fsck_buffer(null_oid(the_hash_algo), type, buf, size, &opts)) + if (fsck_buffer(null_oid(istate->repo->hash_algo), type, buf, size, &opts)) die(_("refusing to create malformed object")); fsck_finish(&opts); } if (write_object) - ret = write_object_file(buf, size, type, oid); + ret = odb_write_object(istate->repo->objects, buf, size, type, oid); else - hash_object_file(the_hash_algo, buf, size, type, oid); + hash_object_file(istate->repo->hash_algo, buf, size, type, oid); strbuf_release(&nbuf); return ret; @@ -1199,10 +1188,10 @@ static int index_stream_convert_blob(struct index_state *istate, get_conv_flags(flags)); if (write_object) - ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB, - oid); + ret = odb_write_object(istate->repo->objects, sbuf.buf, sbuf.len, OBJ_BLOB, + oid); else - hash_object_file(the_hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB, + hash_object_file(istate->repo->hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB, oid); strbuf_release(&sbuf); return ret; @@ -1240,7 +1229,7 @@ static int index_core(struct index_state *istate, if (read_result < 0) ret = error_errno(_("read error while indexing %s"), path ? path : "<unknown>"); - else if (read_result != size) + else if ((size_t) read_result != size) ret = error(_("short read while indexing %s"), path ? path : "<unknown>"); else @@ -1268,7 +1257,7 @@ int index_fd(struct index_state *istate, struct object_id *oid, ret = index_stream_convert_blob(istate, oid, fd, path, flags); else if (!S_ISREG(st->st_mode)) ret = index_pipe(istate, oid, fd, type, path, flags); - else if (st->st_size <= repo_settings_get_big_file_threshold(the_repository) || + else if ((st->st_size >= 0 && (size_t) st->st_size <= repo_settings_get_big_file_threshold(istate->repo)) || type != OBJ_BLOB || (path && would_convert_to_git(istate, path))) ret = index_core(istate, oid, fd, xsize_t(st->st_size), @@ -1300,14 +1289,14 @@ int index_path(struct index_state *istate, struct object_id *oid, if (strbuf_readlink(&sb, path, st->st_size)) return error_errno("readlink(\"%s\")", path); if (!(flags & INDEX_WRITE_OBJECT)) - hash_object_file(the_hash_algo, sb.buf, sb.len, + hash_object_file(istate->repo->hash_algo, sb.buf, sb.len, OBJ_BLOB, oid); - else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid)) + else if (odb_write_object(istate->repo->objects, sb.buf, sb.len, OBJ_BLOB, oid)) rc = error(_("%s: failed to insert into database"), path); strbuf_release(&sb); break; case S_IFDIR: - return repo_resolve_gitlink_ref(the_repository, path, "HEAD", oid); + return repo_resolve_gitlink_ref(istate->repo, path, "HEAD", oid); default: return error(_("%s: unsupported file type"), path); } @@ -1329,12 +1318,13 @@ int read_pack_header(int fd, struct pack_header *header) return 0; } -int for_each_file_in_obj_subdir(unsigned int subdir_nr, - struct strbuf *path, - each_loose_object_fn obj_cb, - each_loose_cruft_fn cruft_cb, - each_loose_subdir_fn subdir_cb, - void *data) +static int for_each_file_in_obj_subdir(unsigned int subdir_nr, + struct strbuf *path, + const struct git_hash_algo *algop, + each_loose_object_fn obj_cb, + each_loose_cruft_fn cruft_cb, + each_loose_subdir_fn subdir_cb, + void *data) { size_t origlen, baselen; DIR *dir; @@ -1367,12 +1357,12 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr, namelen = strlen(de->d_name); strbuf_setlen(path, baselen); strbuf_add(path, de->d_name, namelen); - if (namelen == the_hash_algo->hexsz - 2 && + if (namelen == algop->hexsz - 2 && !hex_to_bytes(oid.hash + 1, de->d_name, - the_hash_algo->rawsz - 1)) { - oid_set_algo(&oid, the_hash_algo); - memset(oid.hash + the_hash_algo->rawsz, 0, - GIT_MAX_RAWSZ - the_hash_algo->rawsz); + algop->rawsz - 1)) { + oid_set_algo(&oid, algop); + memset(oid.hash + algop->rawsz, 0, + GIT_MAX_RAWSZ - algop->rawsz); if (obj_cb) { r = obj_cb(&oid, path->buf, data); if (r) @@ -1398,26 +1388,7 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr, return r; } -int for_each_loose_file_in_objdir_buf(struct strbuf *path, - each_loose_object_fn obj_cb, - each_loose_cruft_fn cruft_cb, - each_loose_subdir_fn subdir_cb, - void *data) -{ - int r = 0; - int i; - - for (i = 0; i < 256; i++) { - r = for_each_file_in_obj_subdir(i, path, obj_cb, cruft_cb, - subdir_cb, data); - if (r) - break; - } - - return r; -} - -int for_each_loose_file_in_objdir(const char *path, +int for_each_loose_file_in_source(struct odb_source *source, each_loose_object_fn obj_cb, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, @@ -1426,22 +1397,27 @@ int for_each_loose_file_in_objdir(const char *path, struct strbuf buf = STRBUF_INIT; int r; - strbuf_addstr(&buf, path); - r = for_each_loose_file_in_objdir_buf(&buf, obj_cb, cruft_cb, - subdir_cb, data); - strbuf_release(&buf); + strbuf_addstr(&buf, source->path); + for (int i = 0; i < 256; i++) { + r = for_each_file_in_obj_subdir(i, &buf, source->odb->repo->hash_algo, + obj_cb, cruft_cb, subdir_cb, data); + if (r) + break; + } + strbuf_release(&buf); return r; } -int for_each_loose_object(each_loose_object_fn cb, void *data, +int for_each_loose_object(struct object_database *odb, + each_loose_object_fn cb, void *data, enum for_each_object_flags flags) { struct odb_source *source; - odb_prepare_alternates(the_repository->objects); - for (source = the_repository->objects->sources; source; source = source->next) { - int r = for_each_loose_file_in_objdir(source->path, cb, NULL, + odb_prepare_alternates(odb); + for (source = odb->sources; source; source = source->next) { + int r = for_each_loose_file_in_source(source, cb, NULL, NULL, data); if (r) return r; @@ -1472,7 +1448,7 @@ struct oidtree *odb_loose_cache(struct odb_source *source, uint32_t *bitmap; if (subdir_nr < 0 || - subdir_nr >= bitsizeof(source->loose_objects_subdir_seen)) + (size_t) subdir_nr >= bitsizeof(source->loose_objects_subdir_seen)) BUG("subdir_nr out of range"); bitmap = &source->loose_objects_subdir_seen[word_index]; @@ -1484,6 +1460,7 @@ struct oidtree *odb_loose_cache(struct odb_source *source, } strbuf_addstr(&buf, source->path); for_each_file_in_obj_subdir(subdir_nr, &buf, + source->odb->repo->hash_algo, append_loose_object, NULL, NULL, source->loose_objects_cache); @@ -1504,7 +1481,8 @@ static int check_stream_oid(git_zstream *stream, const char *hdr, unsigned long size, const char *path, - const struct object_id *expected_oid) + const struct object_id *expected_oid, + const struct git_hash_algo *algop) { struct git_hash_ctx c; struct object_id real_oid; @@ -1512,7 +1490,7 @@ static int check_stream_oid(git_zstream *stream, unsigned long total_read; int status = Z_OK; - the_hash_algo->init_fn(&c); + algop->init_fn(&c); git_hash_update(&c, hdr, stream->total_out); /* @@ -1557,7 +1535,8 @@ static int check_stream_oid(git_zstream *stream, return 0; } -int read_loose_object(const char *path, +int read_loose_object(struct repository *repo, + const char *path, const struct object_id *expected_oid, struct object_id *real_oid, void **contents, @@ -1596,8 +1575,9 @@ int read_loose_object(const char *path, } if (*oi->typep == OBJ_BLOB && - *size > repo_settings_get_big_file_threshold(the_repository)) { - if (check_stream_oid(&stream, hdr, *size, path, expected_oid) < 0) + *size > repo_settings_get_big_file_threshold(repo)) { + if (check_stream_oid(&stream, hdr, *size, path, expected_oid, + repo->hash_algo) < 0) goto out_inflate; } else { *contents = unpack_loose_rest(&stream, hdr, *size, expected_oid); @@ -1605,7 +1585,7 @@ int read_loose_object(const char *path, error(_("unable to unpack contents of %s"), path); goto out_inflate; } - hash_object_file(the_repository->hash_algo, + hash_object_file(repo->hash_algo, *contents, *size, *oi->typep, real_oid); if (!oideq(expected_oid, real_oid)) diff --git a/object-file.h b/object-file.h index 67b4ffc480..15d97630d3 100644 --- a/object-file.h +++ b/object-file.h @@ -45,13 +45,12 @@ const char *odb_loose_path(struct odb_source *source, const struct object_id *oid); /* - * Return true iff an alternate object database has a loose object + * Return true iff an object database source has a loose object * with the specified name. This function does not respect replace * references. */ -int has_loose_object_nonlocal(const struct object_id *); - -int has_loose_object(const struct object_id *); +int has_loose_object(struct odb_source *source, + const struct object_id *oid); void *map_loose_object(struct repository *r, const struct object_id *oid, unsigned long *size); @@ -87,22 +86,11 @@ typedef int each_loose_cruft_fn(const char *basename, typedef int each_loose_subdir_fn(unsigned int nr, const char *path, void *data); -int for_each_file_in_obj_subdir(unsigned int subdir_nr, - struct strbuf *path, - each_loose_object_fn obj_cb, - each_loose_cruft_fn cruft_cb, - each_loose_subdir_fn subdir_cb, - void *data); -int for_each_loose_file_in_objdir(const char *path, +int for_each_loose_file_in_source(struct odb_source *source, each_loose_object_fn obj_cb, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, void *data); -int for_each_loose_file_in_objdir_buf(struct strbuf *path, - each_loose_object_fn obj_cb, - each_loose_cruft_fn cruft_cb, - each_loose_subdir_fn subdir_cb, - void *data); /* * Iterate over all accessible loose objects without respect to @@ -111,7 +99,8 @@ int for_each_loose_file_in_objdir_buf(struct strbuf *path, * * Any flags specific to packs are ignored. */ -int for_each_loose_object(each_loose_object_fn, void *, +int for_each_loose_object(struct object_database *odb, + each_loose_object_fn, void *, enum for_each_object_flags flags); @@ -157,29 +146,10 @@ enum unpack_loose_header_result unpack_loose_header(git_zstream *stream, struct object_info; int parse_loose_header(const char *hdr, struct object_info *oi); -enum { - /* - * By default, `write_object_file()` does not actually write - * anything into the object store, but only computes the object ID. - * This flag changes that so that the object will be written as a loose - * object and persisted. - */ - WRITE_OBJECT_FILE_PERSIST = (1 << 0), - - /* - * Do not print an error in case something gose wrong. - */ - WRITE_OBJECT_FILE_SILENT = (1 << 1), -}; - -int write_object_file_flags(const void *buf, unsigned long len, - enum object_type type, struct object_id *oid, - struct object_id *compat_oid_in, unsigned flags); -static inline int write_object_file(const void *buf, unsigned long len, - enum object_type type, struct object_id *oid) -{ - return write_object_file_flags(buf, len, type, oid, NULL, 0); -} +int write_object_file(struct odb_source *source, + const void *buf, unsigned long len, + enum object_type type, struct object_id *oid, + struct object_id *compat_oid_in, unsigned flags); struct input_stream { const void *(*read)(struct input_stream *, unsigned long *len); @@ -187,10 +157,12 @@ struct input_stream { int is_finished; }; -int stream_loose_object(struct input_stream *in_stream, size_t len, +int stream_loose_object(struct odb_source *source, + struct input_stream *in_stream, size_t len, struct object_id *oid); -int force_object_loose(const struct object_id *oid, time_t mtime); +int force_object_loose(struct odb_source *source, + const struct object_id *oid, time_t mtime); /** * With in-core object data in "buf", rehash it to make sure the @@ -218,8 +190,10 @@ enum finalize_object_file_flags { FOF_SKIP_COLLISION_CHECK = 1, }; -int finalize_object_file(const char *tmpfile, const char *filename); -int finalize_object_file_flags(const char *tmpfile, const char *filename, +int finalize_object_file(struct repository *repo, + const char *tmpfile, const char *filename); +int finalize_object_file_flags(struct repository *repo, + const char *tmpfile, const char *filename, enum finalize_object_file_flags flags); void hash_object_file(const struct git_hash_algo *algo, const void *buf, @@ -237,7 +211,8 @@ int check_and_freshen_file(const char *fn, int freshen); * * Returns 0 on success, negative on error (details may be written to stderr). */ -int read_loose_object(const char *path, +int read_loose_object(struct repository *repo, + const char *path, const struct object_id *expected_oid, struct object_id *real_oid, void **contents, @@ -980,6 +980,16 @@ void odb_assert_oid_type(struct object_database *odb, type_name(expect)); } +int odb_write_object_ext(struct object_database *odb, + const void *buf, unsigned long len, + enum object_type type, + struct object_id *oid, + struct object_id *compat_oid, + unsigned flags) +{ + return write_object_file(odb->sources, buf, len, type, oid, compat_oid, flags); +} + struct object_database *odb_new(struct repository *repo) { struct object_database *o = xmalloc(sizeof(*o)); @@ -437,6 +437,44 @@ enum for_each_object_flags { FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS = (1<<4), }; +enum { + /* + * By default, `odb_write_object()` does not actually write anything + * into the object store, but only computes the object ID. This flag + * changes that so that the object will be written as a loose object + * and persisted. + */ + WRITE_OBJECT_PERSIST = (1 << 0), + + /* + * Do not print an error in case something goes wrong. + */ + WRITE_OBJECT_SILENT = (1 << 1), +}; + +/* + * Write an object into the object database. The object is being written into + * the local alternate of the repository. If provided, the converted object ID + * as well as the compatibility object ID are written to the respective + * pointers. + * + * Returns 0 on success, a negative error code otherwise. + */ +int odb_write_object_ext(struct object_database *odb, + const void *buf, unsigned long len, + enum object_type type, + struct object_id *oid, + struct object_id *compat_oid, + unsigned flags); + +static inline int odb_write_object(struct object_database *odb, + const void *buf, unsigned long len, + enum object_type type, + struct object_id *oid) +{ + return odb_write_object_ext(odb, buf, len, type, oid, NULL, 0); +} + /* Compatibility wrappers, to be removed once Git 2.51 has been released. */ #include "repository.h" diff --git a/pack-write.c b/pack-write.c index eccdc798e3..83eaf88541 100644 --- a/pack-write.c +++ b/pack-write.c @@ -538,22 +538,24 @@ struct hashfile *create_tmp_packfile(struct repository *repo, return hashfd(repo->hash_algo, fd, *pack_tmp_name); } -static void rename_tmp_packfile(struct strbuf *name_prefix, const char *source, +static void rename_tmp_packfile(struct repository *repo, + struct strbuf *name_prefix, const char *source, const char *ext) { size_t name_prefix_len = name_prefix->len; strbuf_addstr(name_prefix, ext); - if (finalize_object_file(source, name_prefix->buf)) + if (finalize_object_file(repo, source, name_prefix->buf)) die("unable to rename temporary file to '%s'", name_prefix->buf); strbuf_setlen(name_prefix, name_prefix_len); } -void rename_tmp_packfile_idx(struct strbuf *name_buffer, +void rename_tmp_packfile_idx(struct repository *repo, + struct strbuf *name_buffer, char **idx_tmp_name) { - rename_tmp_packfile(name_buffer, *idx_tmp_name, "idx"); + rename_tmp_packfile(repo, name_buffer, *idx_tmp_name, "idx"); } void stage_tmp_packfiles(struct repository *repo, @@ -586,11 +588,11 @@ void stage_tmp_packfiles(struct repository *repo, hash); } - rename_tmp_packfile(name_buffer, pack_tmp_name, "pack"); + rename_tmp_packfile(repo, name_buffer, pack_tmp_name, "pack"); if (rev_tmp_name) - rename_tmp_packfile(name_buffer, rev_tmp_name, "rev"); + rename_tmp_packfile(repo, name_buffer, rev_tmp_name, "rev"); if (mtimes_tmp_name) - rename_tmp_packfile(name_buffer, mtimes_tmp_name, "mtimes"); + rename_tmp_packfile(repo, name_buffer, mtimes_tmp_name, "mtimes"); free(rev_tmp_name); free(mtimes_tmp_name); @@ -145,7 +145,8 @@ void stage_tmp_packfiles(struct repository *repo, struct pack_idx_option *pack_idx_opts, unsigned char hash[], char **idx_tmp_name); -void rename_tmp_packfile_idx(struct strbuf *basename, +void rename_tmp_packfile_idx(struct repository *repo, + struct strbuf *basename, char **idx_tmp_name); #endif diff --git a/prune-packed.c b/prune-packed.c index 92fb4fbb0e..d49dc11957 100644 --- a/prune-packed.c +++ b/prune-packed.c @@ -40,7 +40,7 @@ void prune_packed_objects(int opts) progress = start_delayed_progress(the_repository, _("Removing duplicate objects"), 256); - for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), + for_each_loose_file_in_source(the_repository->objects->sources, prune_object, NULL, prune_subdir, &opts); /* Ensure we show 100% before finishing progress */ diff --git a/reachable.c b/reachable.c index 8330a14fa8..22266db523 100644 --- a/reachable.c +++ b/reachable.c @@ -319,7 +319,7 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs, oidset_init(&data.extra_recent_oids, 0); data.extra_recent_oids_loaded = 0; - r = for_each_loose_object(add_recent_loose, &data, + r = for_each_loose_object(the_repository->objects, add_recent_loose, &data, FOR_EACH_OBJECT_LOCAL_ONLY); if (r) goto done; diff --git a/read-cache.c b/read-cache.c index 4fdde758d1..06ad74db22 100644 --- a/read-cache.c +++ b/read-cache.c @@ -690,7 +690,7 @@ static struct cache_entry *create_alias_ce(struct index_state *istate, void set_object_name_for_intent_to_add_entry(struct cache_entry *ce) { struct object_id oid; - if (write_object_file("", 0, OBJ_BLOB, &oid)) + if (odb_write_object(the_repository->objects, "", 0, OBJ_BLOB, &oid)) die(_("cannot create an empty blob in the object database")); oidcpy(&ce->oid, &oid); } diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index d6a501d453..fd3e7e355e 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1482,4 +1482,27 @@ test_expect_success '`submodule init` and `init.templateDir`' ' ) ' +test_expect_success 'submodule add fails when name is reused' ' + git init test-submodule && + ( + cd test-submodule && + git commit --allow-empty -m init && + + git init ../child-origin && + git -C ../child-origin commit --allow-empty -m init && + + git submodule add ../child-origin child && + git commit -m "Add submodule child" && + + git mv child child_old && + git commit -m "Move child to child_old" && + + # Now adding a *new* repo at the old name must fail + git init ../child2-origin && + git -C ../child2-origin commit --allow-empty -m init && + test_must_fail git submodule add ../child2-origin child 2>err && + test_grep "already used for" err + ) +' + test_done diff --git a/t/t7413-submodule-is-active.sh b/t/t7413-submodule-is-active.sh index 9509dc18fd..6fd3b870de 100755 --- a/t/t7413-submodule-is-active.sh +++ b/t/t7413-submodule-is-active.sh @@ -124,4 +124,19 @@ test_expect_success 'is-active, submodule.active and submodule add' ' git -C super2 config --get submodule.mod.active ' +test_expect_success 'submodule add skips redundant active entry' ' + git init repo && + ( + cd repo && + git config submodule.active "lib/*" && + git commit --allow-empty -m init && + + git init ../lib-origin && + git -C ../lib-origin commit --allow-empty -m init && + + git submodule add ../lib-origin lib/foo && + test_must_fail git config --get submodule.lib/foo.active + ) +' + test_done diff --git a/tmp-objdir.c b/tmp-objdir.c index ae01eae9c4..9f5a1788cd 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -227,7 +227,7 @@ static int migrate_one(struct tmp_objdir *t, return -1; return migrate_paths(t, src, dst, flags); } - return finalize_object_file_flags(src->buf, dst->buf, flags); + return finalize_object_file_flags(t->repo, src->buf, dst->buf, flags); } static int is_loose_object_shard(const char *name) |