diff --git a/Documentation/RelNotes/2.51.0.adoc b/Documentation/RelNotes/2.51.0.adoc index a89d459d2e2db0..a73ea3e8086ce4 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. -------------------------------------------------------------- @@ -92,8 +97,8 @@ Performance, Internal Implementation, Development Support etc. * "git push" and "git fetch" are taught to update refs in batches to gain performance. - * Some code paths in the "git prune" used to ignore passed in - repository object and used the_repository singleton instance + * Some code paths in "git prune" used to ignore the passed-in + repository object and used the `the_repository` singleton instance instead, which has been corrected. * Update ".clang-format" and ".editorconfig" to match our style guide @@ -134,7 +139,10 @@ Performance, Internal Implementation, Development Support etc. * Redefine where the multi-pack-index sits in the object subsystem, which recently was restructured to allow multiple backends that support a single object source that belongs to one repository. A - midx does span mulitple "object sources". + MIDX does span multiple "object sources". + + * Reduce implicit assumption and dependence on the_repository in the + object-file subsystem. Fixes since v2.50 @@ -284,6 +292,15 @@ including security updates, are included in this release. and also they learn to honor the -U command-line option. (merge 2b3ae04011 lm/add-p-context later to maint). + * The case where a new submodule takes a path where there used to be a + completely different subproject is now dealt with a bit better than + before. + (merge 5ed8c5b465 kj/renamed-submodule later to maint). + + * The deflate codepath in "git archive --format=zip" had a + longstanding bug coming from misuse of zlib API, which has been + corrected. + * 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). @@ -320,3 +337,5 @@ including security updates, are included in this release. (merge 3bdd897413 ms/meson-with-ancient-git-wo-ls-files-dedup later to maint). (merge cca758d324 kh/doc-fast-import-historical later to maint). (merge 9b0781196a jc/test-hashmap-is-still-here later to maint). + (merge 1bad05bacc jk/revert-squelch-compiler-warning later to maint). + (merge 3a7e783d9c dl/squelch-maybe-uninitialized later to maint). diff --git a/Documentation/git-submodule.adoc b/Documentation/git-submodule.adoc index 87d8e0f0c563b7..503c84a200c929 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), diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 63463c87739aa0..e7e91190ae2d0d 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,6 +1,6 @@ #!/bin/sh -DEF_VER=v2.50.GIT +DEF_VER=v2.51.0-rc1 LF=' ' diff --git a/apply.c b/apply.c index 47fa883b45a02a..bf1260b51d2c2d 100644 --- a/apply.c +++ b/apply.c @@ -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/archive-zip.c b/archive-zip.c index dbd90d9c3d4b32..bea5bdd43dc43e 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -492,14 +492,22 @@ static int write_zip_entry(struct archiver_args *args, zstream.next_in = buf; zstream.avail_in = 0; - result = git_deflate(&zstream, Z_FINISH); - if (result != Z_STREAM_END) - die("deflate error (%d)", result); + + do { + result = git_deflate(&zstream, Z_FINISH); + if (result != Z_OK && result != Z_STREAM_END) + die("deflate error (%d)", result); + + out_len = zstream.next_out - compressed; + if (out_len > 0) { + write_or_die(1, compressed, out_len); + compressed_size += out_len; + zstream.next_out = compressed; + zstream.avail_out = sizeof(compressed); + } + } while (result != Z_STREAM_END); git_deflate_end(&zstream); - out_len = zstream.next_out - compressed; - write_or_die(1, compressed, out_len); - compressed_size += out_len; zip_offset += compressed_size; write_zip_data_desc(size, compressed_size, crc); diff --git a/builtin/cat-file.c b/builtin/cat-file.c index b9eb2bb3b923ac..fce0b06451c5cd 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 c2f5df03348db5..72347addd208b8 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 b1148a68fa826f..a61d3b46aac627 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 adf3994be17e74..2c35f9345d02d7 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 0ec6ca06e3b083..543a2cdb5cd864 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 6fd4dc26be581f..0edd94a76f2958 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 53f1a7cd71ec96..f91c301bba9fbd 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 3da4ca2c8cfe59..46775d0c79f454 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 e078c97d032d95..7cf6e1230ac450 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 81df7f6099fa4e..12772303f504f3 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 d2252cf5346b81..6fb4144da3ead5 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 1f084a1b8dfa0c..53a225625039ea 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 d1c0ee1419931c..55635a891f37d6 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 82d516a42c46b6..1113137a6f0b3f 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/remote.c b/builtin/remote.c index 43a122740af300..8961ae6a8973c7 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1474,10 +1474,13 @@ static int set_head(int argc, const char **argv, const char *prefix, }; argc = parse_options(argc, argv, prefix, options, builtin_remote_sethead_usage, 0); - if (argc) { - strbuf_addf(&b_head, "refs/remotes/%s/HEAD", argv[0]); - remote = remote_get(argv[0]); - } + + /* All modes require at least a remote name. */ + if (!argc) + usage_with_options(builtin_remote_sethead_usage, options); + + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", argv[0]); + remote = remote_get(argv[0]); if (!opt_a && !opt_d && argc == 2) { head_name = xstrdup(argv[1]); diff --git a/builtin/replace.c b/builtin/replace.c index 19897ef927fea8..900b560a77d9d7 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/revert.c b/builtin/revert.c index e07c2217fe846b..c3f92b585df8c9 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -111,7 +111,7 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, const char * const * usage_str = revert_or_cherry_pick_usage(opts); const char *me = action_name(opts); const char *cleanup_arg = NULL; - const char sentinel_value; + const char sentinel_value = 0; /* value not important */ const char *strategy = &sentinel_value; const char *gpg_sign = &sentinel_value; enum empty_action empty_opt = EMPTY_COMMIT_UNSPECIFIED; diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 28f34f7bc183d2..07a1935cbe1a69 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 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 25f30e3f9beb1d..f0665af3acdf6c 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 26aa885da92c85..7ae7c82b6c05a6 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 16df86c0ba89db..b2809ab0398136 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 a4bc14ad15c8a0..66ef2becbe01a4 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; } diff --git a/commit.c b/commit.c index ea84c8e7f67746..d1e1061214b9ab 100644 --- a/commit.c +++ b/commit.c @@ -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 ff6e0be4b4126c..5130b4f0189518 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 5fd885c2bf73e9..3c112af57803a0 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 f2fcead78e8203..69b0b844352bc1 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) @@ -231,10 +193,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 @@ -250,10 +208,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 @@ -267,11 +221,8 @@ dist-version: GIT-VERSION-FILE @sed 's|^GITGUI_VERSION=||' $(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 71b9fa67a4be7f..00000000000000 --- 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 0304937f41e169..00000000000000 --- 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 " - 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 00000000000000..0dd2da92e3b5d4 --- /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 " + 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 similarity index 100% rename from git-gui/git-gui--askpass rename to git-gui/git-gui--askpass.sh diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 6a8a9939d173e5..fa6995530bd287 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -30,7 +30,7 @@ along with this program; if not, see .}] ## ## 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 \ @@ -73,6 +73,26 @@ proc is_Cygwin {} { return $_iscygwin } +###################################################################### +## 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,15 +1126,17 @@ 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] } if {![info exists env(GIT_ASKPASS)]} { - set env(GIT_ASKPASS) [file join [git --exec-path] git-gui--askpass] + set env(GIT_ASKPASS) [file join $argv0dir git-gui--askpass] } if {![info exists env(GIT_ASK_YESNO)]} { - set env(GIT_ASK_YESNO) [file join [git --exec-path] git-gui--askyesno] + set env(GIT_ASK_YESNO) [file join $argv0dir git-gui--askyesno] } +unset argv0dir ###################################################################### ## @@ -1411,15 +1426,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 } @@ -1433,7 +1448,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 } @@ -1490,7 +1504,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] @@ -1536,7 +1550,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] @@ -1569,7 +1583,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]] @@ -1592,7 +1606,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 9d4d1ac8723d36..4477b84eaeb7b5 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 39e0f2dc9864e0..97c9ec1c00f741 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 f53eb952cf3ff4..fe72de025e65da 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 987486a4b6024b..449e89e2bc0c0e 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 7a9e3c83bb9069..cd355cc92a276c 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 2fd57a51fb085a..89eb8c7b739131 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 5bd625bdbdfb24..003e4613f3495b 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 377547034b7d49..7aa09c7728267e 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 2c9bb3af403fe4..44be4ed3ffa597 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 349d31edf3e1c7..f0814efdd7383e 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 1d01d9cbfab0ba..431665059e710c 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 538d61c792defa..634656820dc526 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 8c4a0c2ee7a0de..c18e201d85e69d 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 b6c6dc35003bb3..00000000000000 --- 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 1ade121c4cc532..00000000000000 --- a/git-gui/macosx/Info.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - @@GITGUI_TKEXECUTABLE@@ - CFBundleGetInfoString - Git Gui @@GITGUI_VERSION@@ © 2006-2007 Shawn Pearce, et. al. - CFBundleIconFile - git-gui.icns - CFBundleIdentifier - cz.or.repo.git-gui - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Git Gui - CFBundlePackageType - APPL - CFBundleShortVersionString - @@GITGUI_VERSION@@ - CFBundleSignature - GITg - CFBundleVersion - @@GITGUI_VERSION@@ - NSHighResolutionCapable - - - diff --git a/git-gui/macosx/git-gui.icns b/git-gui/macosx/git-gui.icns deleted file mode 100644 index 77d88a77a76696..00000000000000 Binary files a/git-gui/macosx/git-gui.icns and /dev/null differ diff --git a/git-gui/meson.build b/git-gui/meson.build index cdae85e4b9dce7..320ba09ecfeb32 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,54 +51,22 @@ 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, diff --git a/git-gui/po/bg.po b/git-gui/po/bg.po index 70ab2b438ab6d5..21f5bd54e9f3cd 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 \n" "Language-Team: Bulgarian \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 b1845c505500a0..38debe376c2a8f 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] diff --git a/git.c b/git.c index d4a9ca63c95a5d..ac75336f5ff07a 100644 --- a/git.c +++ b/git.c @@ -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] == '!') { diff --git a/gitk-git/gitk b/gitk-git/gitk index 427a8a96c9b1e3..3b6acfc5922086 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -7,7 +7,7 @@ exec wish "$0" -- "$@" # and distributed under the terms of the GNU General Public Licence, # either version 2, or (at your option) any later version. -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 \ @@ -33,6 +33,26 @@ The version of git found is $git_version." exit 1 } +###################################################################### +## 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] + } +} + ###################################################################### ## ## Enabling platform-specific code paths @@ -2033,8 +2053,10 @@ proc readrefs {} { set tagids($name) $id lappend idtags($id) $name } else { - set otherrefids($name) $id - lappend idotherrefs($id) $name + if [is_other_ref_visible $name] { + set otherrefids($name) $id + lappend idotherrefs($id) $name + } } } catch {close $refd} @@ -2288,6 +2310,16 @@ proc bind_mousewheel {} { bind $cflist {$cflist yview scroll [scrollval %D 2] units} bind $cflist break bind $canv {$canv xview scroll [scrollval %D] units} + + if {[package vcompare $::tcl_version 8.7] >= 0} { + bindall {allcanvs yview scroll [scrollval 5*%D] units} + bindall break + bind $ctext {$ctext yview scroll [scrollval 5*%D 2] units} + bind $ctext {$ctext xview scroll [scrollval 5*%D 2] units} + bind $cflist {$cflist yview scroll [scrollval 5*%D 2] units} + bind $cflist break + bind $canv {$canv xview scroll [scrollval 5*%D] units} + } } proc bind_mousewheel_buttons {} { @@ -2747,7 +2779,7 @@ proc makewindow {} { bindall <1> {selcanvline %W %x %y} #Mouse / touchpad scrolling - if {[tk windowingsystem] == "win32"} { + if {[tk windowingsystem] == "win32" || [package vcompare $::tcl_version 8.7] >= 0} { set scroll_D0 120 bind_mousewheel } elseif {[tk windowingsystem] == "x11"} { @@ -7794,7 +7826,7 @@ proc gettree {id} { set treepending $id set treefilelist($id) {} set treeidlist($id) {} - fconfigure $gtf -blocking 0 -encoding binary + fconfigure $gtf -blocking 0 -translation binary filerun $gtf [list gettreeline $gtf $id] } } else { @@ -7821,7 +7853,7 @@ proc gettreeline {gtf id} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom utf-8 $fname] + set fname [convertfrom utf-8 $fname] lappend treefilelist($id) $fname } if {![eof $gtf]} { @@ -8055,7 +8087,7 @@ proc gettreediffs {ids} { set treepending $ids set treediff {} - fconfigure $gdtf -blocking 0 -encoding binary + fconfigure $gdtf -blocking 0 -translation binary filerun $gdtf [list gettreediffline $gdtf $ids] } @@ -8081,7 +8113,7 @@ proc gettreediffline {gdtf ids} { if {[string index $file 0] eq "\""} { set file [lindex $file 0] } - set file [encoding convertfrom utf-8 $file] + set file [convertfrom utf-8 $file] if {$file ne [lindex $treediff end]} { lappend treediff $file lappend sublist $file @@ -8166,7 +8198,7 @@ proc getblobdiffs {ids} { error_popup [mc "Error getting diffs: %s" $err] return } - fconfigure $bdf -blocking 0 -encoding binary -eofchar {} + fconfigure $bdf -blocking 0 -translation binary set blobdifffd($ids) $bdf initblobdiffvars filerun $bdf [list getblobdiffline $bdf $diffids] @@ -8217,7 +8249,7 @@ proc makediffhdr {fname ids} { global ctext curdiffstart treediffs diffencoding global ctext_file_names jump_to_here targetline diffline - set fname [encoding convertfrom utf-8 $fname] + set fname [convertfrom utf-8 $fname] set diffencoding [get_path_encoding $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { @@ -8279,7 +8311,7 @@ proc parseblobdiffline {ids line} { if {![string compare -length 5 "diff " $line]} { if {![regexp {^diff (--cc|--git) } $line m type]} { - set line [encoding convertfrom utf-8 $line] + set line [convertfrom utf-8 $line] $ctext insert end "$line\n" hunksep continue } @@ -8328,7 +8360,7 @@ proc parseblobdiffline {ids line} { makediffhdr $fname $ids } elseif {![string compare -length 16 "* Unmerged path " $line]} { - set fname [encoding convertfrom utf-8 [string range $line 16 end]] + set fname [convertfrom utf-8 [string range $line 16 end]] $ctext insert end "\n" set curdiffstart [$ctext index "end - 1c"] lappend ctext_file_names $fname @@ -8341,7 +8373,7 @@ proc parseblobdiffline {ids line} { } elseif {![string compare -length 2 "@@" $line]} { regexp {^@@+} $line ats - set line [encoding convertfrom $diffencoding $line] + set line [convertfrom $diffencoding $line] $ctext insert end "$line\n" hunksep if {[regexp { \+(\d+),\d+ @@} $line m nl]} { set diffline $nl @@ -8370,10 +8402,10 @@ proc parseblobdiffline {ids line} { $ctext insert end "$line\n" filesep } } elseif {$currdiffsubmod != "" && ![string compare -length 3 " >" $line]} { - set line [encoding convertfrom $diffencoding $line] + set line [convertfrom $diffencoding $line] $ctext insert end "$line\n" dresult } elseif {$currdiffsubmod != "" && ![string compare -length 3 " <" $line]} { - set line [encoding convertfrom $diffencoding $line] + set line [convertfrom $diffencoding $line] $ctext insert end "$line\n" d0 } elseif {$diffinhdr} { if {![string compare -length 12 "rename from " $line]} { @@ -8381,7 +8413,7 @@ proc parseblobdiffline {ids line} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom utf-8 $fname] + set fname [convertfrom utf-8 $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { setinlist difffilestart $i $curdiffstart @@ -8400,12 +8432,12 @@ proc parseblobdiffline {ids line} { set diffinhdr 0 return } - set line [encoding convertfrom utf-8 $line] + set line [convertfrom utf-8 $line] $ctext insert end "$line\n" filesep } else { set line [string map {\x1A ^Z} \ - [encoding convertfrom $diffencoding $line]] + [convertfrom $diffencoding $line]] # parse the prefix - one ' ', '-' or '+' for each parent set prefix [string range $line 0 [expr {$diffnparents - 1}]] set tag [expr {$diffnparents > 1? "m": "d"}] @@ -10238,7 +10270,7 @@ proc refill_reflist {} { if {![string match "remotes/*" $n] && [string match $reflistfilter $n]} { if {[commitinview $headids($n) $curview]} { lappend localrefs [list $n H] - if {[info exists upstreamofref($n)]} { + if {[info exists upstreamofref($n)] && [commitinview $headids($upstreamofref($n)) $curview]} { lappend trackedremoterefs [list $upstreamofref($n) R] } } else { @@ -10246,7 +10278,7 @@ proc refill_reflist {} { } } } - set trackedremoterefs [lsort -index 0 $trackedremoterefs] + set trackedremoterefs [lsort -index 0 -unique $trackedremoterefs] set localrefs [lsort -index 0 $localrefs] foreach n [array names headids] { @@ -11649,6 +11681,13 @@ proc prefspage_general {notebook} { -variable hideremotes grid x $page.hideremotes -sticky w + ttk::entry $page.refstohide -textvariable refstohide + ttk::frame $page.refstohidef + ttk::label $page.refstohidef.l -text [mc "Refs to hide (space-separated globs)" ] + pack $page.refstohidef.l -side left + pack configure $page.refstohidef.l -padx 10 + grid x $page.refstohidef $page.refstohide -sticky ew + ttk::checkbutton $page.autocopy -text [mc "Copy commit ID to clipboard"] \ -variable autocopy grid x $page.autocopy -sticky w @@ -11720,57 +11759,63 @@ proc prefspage_colors {notebook} { grid $page.cdisp - -sticky w -pady 10 label $page.ui -padx 40 -relief sunk -background $uicolor ttk::button $page.uibut -text [mc "Interface"] \ - -command [list choosecolor uicolor {} $page.ui [mc "interface"] setui] + -command [list choosecolor uicolor {} $page [mc "interface"]] grid x $page.uibut $page.ui -sticky w label $page.bg -padx 40 -relief sunk -background $bgcolor ttk::button $page.bgbut -text [mc "Background"] \ - -command [list choosecolor bgcolor {} $page.bg [mc "background"] setbg] + -command [list choosecolor bgcolor {} $page [mc "background"]] grid x $page.bgbut $page.bg -sticky w label $page.fg -padx 40 -relief sunk -background $fgcolor ttk::button $page.fgbut -text [mc "Foreground"] \ - -command [list choosecolor fgcolor {} $page.fg [mc "foreground"] setfg] + -command [list choosecolor fgcolor {} $page [mc "foreground"]] grid x $page.fgbut $page.fg -sticky w label $page.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0] ttk::button $page.diffoldbut -text [mc "Diff: old lines"] \ - -command [list choosecolor diffcolors 0 $page.diffold [mc "diff old lines"] \ - [list $ctext tag conf d0 -foreground]] + -command [list choosecolor diffcolors 0 $page [mc "diff old lines"]] grid x $page.diffoldbut $page.diffold -sticky w label $page.diffoldbg -padx 40 -relief sunk -background [lindex $diffbgcolors 0] ttk::button $page.diffoldbgbut -text [mc "Diff: old lines bg"] \ - -command [list choosecolor diffbgcolors 0 $page.diffoldbg \ - [mc "diff old lines bg"] \ - [list $ctext tag conf d0 -background]] + -command [list choosecolor diffbgcolors 0 $page [mc "diff old lines bg"]] grid x $page.diffoldbgbut $page.diffoldbg -sticky w label $page.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1] ttk::button $page.diffnewbut -text [mc "Diff: new lines"] \ - -command [list choosecolor diffcolors 1 $page.diffnew [mc "diff new lines"] \ - [list $ctext tag conf dresult -foreground]] + -command [list choosecolor diffcolors 1 $page [mc "diff new lines"]] grid x $page.diffnewbut $page.diffnew -sticky w label $page.diffnewbg -padx 40 -relief sunk -background [lindex $diffbgcolors 1] ttk::button $page.diffnewbgbut -text [mc "Diff: new lines bg"] \ - -command [list choosecolor diffbgcolors 1 $page.diffnewbg \ - [mc "diff new lines bg"] \ - [list $ctext tag conf dresult -background]] + -command [list choosecolor diffbgcolors 1 $page [mc "diff new lines bg"]] grid x $page.diffnewbgbut $page.diffnewbg -sticky w label $page.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2] ttk::button $page.hunksepbut -text [mc "Diff: hunk header"] \ - -command [list choosecolor diffcolors 2 $page.hunksep \ - [mc "diff hunk header"] \ - [list $ctext tag conf hunksep -foreground]] + -command [list choosecolor diffcolors 2 $page [mc "diff hunk header"]] grid x $page.hunksepbut $page.hunksep -sticky w label $page.markbgsep -padx 40 -relief sunk -background $markbgcolor ttk::button $page.markbgbut -text [mc "Marked line bg"] \ - -command [list choosecolor markbgcolor {} $page.markbgsep \ - [mc "marked line background"] \ - [list $ctext tag conf omark -background]] + -command [list choosecolor markbgcolor {} $page [mc "marked line background"]] grid x $page.markbgbut $page.markbgsep -sticky w label $page.selbgsep -padx 40 -relief sunk -background $selectbgcolor ttk::button $page.selbgbut -text [mc "Select bg"] \ - -command [list choosecolor selectbgcolor {} $page.selbgsep [mc "background"] setselbg] + -command [list choosecolor selectbgcolor {} $page [mc "background"]] grid x $page.selbgbut $page.selbgsep -sticky w return $page } +proc prefspage_set_colorswatches {page} { + global uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor + global diffbgcolors + + $page.ui configure -background $uicolor + $page.bg configure -background $bgcolor + $page.fg configure -background $fgcolor + $page.diffold configure -background [lindex $diffcolors 0] + $page.diffoldbg configure -background [lindex $diffbgcolors 0] + $page.diffnew configure -background [lindex $diffcolors 1] + $page.diffnewbg configure -background [lindex $diffbgcolors 1] + $page.hunksep configure -background [lindex $diffcolors 2] + $page.markbgsep configure -background $markbgcolor + $page.selbgsep configure -background $selectbgcolor +} + proc prefspage_fonts {notebook} { set page [create_prefs_page $notebook.fonts] ttk::label $page.cfont -text [mc "Fonts: press to choose"] -font mainfontbold @@ -11838,15 +11883,15 @@ proc choose_extdiff {} { } } -proc choosecolor {v vi w x cmd} { +proc choosecolor {v vi prefspage x} { global $v set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \ -title [mc "Gitk: choose color for %s" $x]] if {$c eq {}} return - $w conf -background $c lset $v $vi $c - eval $cmd $c + set_gui_colors + prefspage_set_colorswatches $prefspage } proc setselbg {c} { @@ -11899,6 +11944,22 @@ proc setfg {c} { $canv itemconf markid -outline $c } +proc set_gui_colors {} { + global uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor + global diffbgcolors + + setui $uicolor + setbg $bgcolor + setfg $fgcolor + $ctext tag conf d0 -foreground [lindex $diffcolors 0] + $ctext tag conf d0 -background [lindex $diffbgcolors 0] + $ctext tag conf dresult -foreground [lindex $diffcolors 1] + $ctext tag conf dresult -background [lindex $diffbgcolors 1] + $ctext tag conf hunksep -foreground [lindex $diffcolors 2] + $ctext tag conf omark -background $markbgcolor + setselbg $selectbgcolor +} + proc prefscan {} { global oldprefs prefstop global {*}$::config_variables @@ -11909,6 +11970,7 @@ proc prefscan {} { catch {destroy $prefstop} unset prefstop fontcan + set_gui_colors } proc prefsok {} { @@ -11960,7 +12022,7 @@ proc prefsok {} { $limitdiffs != $oldprefs(limitdiffs)} { reselectline } - if {$hideremotes != $oldprefs(hideremotes)} { + if {$hideremotes != $oldprefs(hideremotes) || $refstohide != $oldprefs(refstohide)} { rereadrefs } if {$wrapcomment != $oldprefs(wrapcomment)} { @@ -12316,7 +12378,7 @@ proc cache_gitattr {attr pathlist} { foreach row [split $rlist "\n"] { if {[regexp "(.*): $attr: (.*)" $row m path value]} { if {[string index $path 0] eq "\""} { - set path [encoding convertfrom utf-8 [lindex $path 0]] + set path [convertfrom utf-8 [lindex $path 0]] } set path_attr_cache($attr,$path) $value } @@ -12337,6 +12399,23 @@ proc get_path_encoding {path} { return $tcl_enc } +proc is_other_ref_visible {ref} { + global refstohide + + if {$refstohide eq {}} { + return 1 + } + + foreach pat [split $refstohide " "] { + if {$pat eq {}} continue + if {[string match $pat $ref]} { + return 0 + } + } + + return 1 +} + ## For msgcat loading, first locate the installation location. if { [info exists ::env(GITK_MSGSDIR)] } { ## Msgsdir was manually set in the environment. @@ -12444,6 +12523,7 @@ set wrapcomment "none" set wrapdefault "none" set showneartags 1 set hideremotes 0 +set refstohide "" set sortrefsbytype 1 set maxrefs 20 set visiblerefs {"master"} @@ -12531,14 +12611,14 @@ catch { set config_file_tmp [file join $env(XDG_CONFIG_HOME) git gitk-tmp] } else { # default XDG_CONFIG_HOME - set config_file "~/.config/git/gitk" - set config_file_tmp "~/.config/git/gitk-tmp" + set config_file "$env(HOME)/.config/git/gitk" + set config_file_tmp "$env(HOME)/.config/git/gitk-tmp" } if {![file exists $config_file]} { # for backward compatibility use the old config file if it exists - if {[file exists "~/.gitk"]} { - set config_file "~/.gitk" - set config_file_tmp "~/.gitk-tmp" + if {[file exists "$env(HOME)/.gitk"]} { + set config_file "$env(HOME)/.gitk" + set config_file_tmp "$env(HOME)/.gitk-tmp" } elseif {![file exists [file dirname $config_file]]} { file mkdir [file dirname $config_file] } @@ -12587,6 +12667,7 @@ set config_variables { mergecolors perfile_attrs reflinecolor + refstohide remotebgcolor selectbgcolor showlocalchanges @@ -12624,8 +12705,6 @@ eval font create textfontbold [fontflags textfont 1] parsefont uifont $uifont eval font create uifont [fontflags uifont] -setui $uicolor - setoptions # check that we can find a .git directory somewhere... @@ -12814,6 +12893,8 @@ if {[tk windowingsystem] eq "win32"} { focus -force . } +set_gui_colors + getcommits {} # Local variables: diff --git a/gitk-git/po/bg.po b/gitk-git/po/bg.po index 773a04983116aa..d1e7d92425bd77 100644 --- a/gitk-git/po/bg.po +++ b/gitk-git/po/bg.po @@ -1,15 +1,15 @@ # Bulgarian translation of gitk po-file. -# Copyright (C) 2014, 2015, 2019, 2020, 2024 Alexander Shopov . +# Copyright (C) 2014, 2015, 2019, 2020, 2024, 2025 Alexander Shopov . # This file is distributed under the same license as the git package. -# Alexander Shopov , 2014, 2015, 2019, 2020, 2024. +# Alexander Shopov , 2014, 2015, 2019, 2020, 2024, 2025. # # msgid "" msgstr "" "Project-Id-Version: gitk master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-24 11:01+0100\n" -"PO-Revision-Date: 2024-12-24 11:05+0100\n" +"POT-Creation-Date: 2025-07-22 18:34+0200\n" +"PO-Revision-Date: 2025-07-28 13:38+0200\n" "Last-Translator: Alexander Shopov \n" "Language-Team: Bulgarian \n" "Language: bg\n" @@ -18,32 +18,25 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: gitk:139 msgid "Couldn't get list of unmerged files:" msgstr "Списъкът с неслети файлове не може да се получи:" -#: gitk:211 gitk:2430 msgid "Color words" msgstr "Оцветяване на думите" -#: gitk:216 gitk:2430 gitk:8335 gitk:8368 msgid "Markup words" msgstr "Отбелязване на думите" -#: gitk:323 msgid "Error parsing revisions:" msgstr "Грешка при анализ на версиите:" -#: gitk:389 msgid "Error executing --argscmd command:" msgstr "Грешка при изпълнение на командата с „--argscmd“." -#: gitk:402 msgid "No files selected: --merge specified but no files are unmerged." msgstr "" "Не са избрани файлове — указана е опцията „--merge“, но няма неслети файлове." -#: gitk:405 msgid "" "No files selected: --merge specified but no unmerged files are within file " "limit." @@ -51,326 +44,246 @@ msgstr "" "Не са избрани файлове — указана е опцията „--merge“, но няма неслети файлове " "в ограниченията." -#: gitk:430 gitk:585 msgid "Error executing git log:" msgstr "Грешка при изпълнение на „git log“:" -#: gitk:448 gitk:601 msgid "Reading" msgstr "Прочитане" -#: gitk:508 gitk:4596 msgid "Reading commits..." msgstr "Прочитане на подаванията…" -#: gitk:511 gitk:1660 gitk:4599 msgid "No commits selected" msgstr "Не са избрани подавания" -#: gitk:1468 gitk:4116 gitk:12738 msgid "Command line" msgstr "Команден ред" -#: gitk:1534 msgid "Can't parse git log output:" msgstr "Изходът от „git log“ не може да се анализира:" -#: gitk:1763 msgid "No commit information available" msgstr "Липсва информация за подавания" -#: gitk:1930 gitk:1959 gitk:4386 gitk:9875 gitk:11485 gitk:11805 msgid "OK" msgstr "Добре" -#: gitk:1961 gitk:4388 gitk:9311 gitk:9390 gitk:9520 gitk:9606 gitk:9877 -#: gitk:11486 gitk:11806 msgid "Cancel" msgstr "Отказ" -#: gitk:2114 msgid "&Update" msgstr "&Обновяване" -#: gitk:2115 msgid "&Reload" msgstr "&Презареждане" -#: gitk:2116 msgid "Reread re&ferences" msgstr "Прочитане &наново" -#: gitk:2117 msgid "&List references" msgstr "&Изброяване на указателите" -#: gitk:2119 msgid "Start git &gui" msgstr "&Стартиране на „git gui“" -#: gitk:2121 msgid "&Quit" msgstr "&Спиране на програмата" -#: gitk:2113 msgid "&File" msgstr "&Файл" -#: gitk:2125 msgid "&Preferences" msgstr "&Настройки" -#: gitk:2124 msgid "&Edit" msgstr "&Редактиране" -#: gitk:2129 msgid "&New view..." msgstr "&Нов изглед…" -#: gitk:2130 msgid "&Edit view..." msgstr "&Редактиране на изгледа…" -#: gitk:2131 msgid "&Delete view" msgstr "&Изтриване на изгледа" -#: gitk:2133 msgid "&All files" msgstr "&Всички файлове" -#: gitk:2128 msgid "&View" msgstr "&Изглед" -#: gitk:2138 gitk:2148 msgid "&About gitk" msgstr "&Относно gitk" -#: gitk:2139 gitk:2153 msgid "&Key bindings" msgstr "&Клавишни комбинации" -#: gitk:2137 gitk:2152 msgid "&Help" msgstr "Помо&щ" -#: gitk:2230 gitk:8767 msgid "Commit ID:" msgstr "Подаване:" -#: gitk:2274 msgid "Row" msgstr "Ред" -#: gitk:2312 msgid "Find" msgstr "Търсене" -#: gitk:2340 msgid "commit" msgstr "подаване" -#: gitk:2344 gitk:2346 gitk:4758 gitk:4781 gitk:4805 gitk:6826 gitk:6898 -#: gitk:6983 msgid "containing:" msgstr "съдържащо:" -#: gitk:2347 gitk:3597 gitk:3602 gitk:4834 msgid "touching paths:" msgstr "в пътищата:" -#: gitk:2348 gitk:4848 msgid "adding/removing string:" msgstr "добавящо/премахващо низ" -#: gitk:2349 gitk:4850 msgid "changing lines matching:" msgstr "променящо редове напасващи:" -#: gitk:2358 gitk:2360 gitk:4837 msgid "Exact" msgstr "Точно" -#: gitk:2360 gitk:4925 gitk:6794 msgid "IgnCase" msgstr "Без регистър" -#: gitk:2360 gitk:4807 gitk:4923 gitk:6790 msgid "Regexp" msgstr "Рег. израз" -#: gitk:2362 gitk:2363 gitk:4945 gitk:4975 gitk:4982 gitk:6919 gitk:6987 msgid "All fields" msgstr "Всички полета" -#: gitk:2363 gitk:4942 gitk:4975 gitk:6857 msgid "Headline" msgstr "Първи ред" -#: gitk:2364 gitk:4942 gitk:6857 gitk:6987 gitk:7499 msgid "Comments" msgstr "Коментари" -#: gitk:2364 gitk:4942 gitk:4947 gitk:4982 gitk:6857 gitk:7434 gitk:8945 -#: gitk:8960 msgid "Author" msgstr "Автор" -#: gitk:2364 gitk:4942 gitk:6857 gitk:7436 msgid "Committer" msgstr "Подаващ" -#: gitk:2398 msgid "Search" msgstr "Търсене" -#: gitk:2406 msgid "Diff" msgstr "Разлики" -#: gitk:2408 msgid "Old version" msgstr "Стара версия" -#: gitk:2410 msgid "New version" msgstr "Нова версия" -#: gitk:2413 msgid "Lines of context" msgstr "Контекст в редове" -#: gitk:2423 msgid "Ignore space change" msgstr "Празните знаци без значение" -#: gitk:2427 gitk:2429 gitk:8069 gitk:8321 msgid "Line diff" msgstr "Поредови разлики" -#: gitk:2502 msgid "Patch" msgstr "Кръпка" -#: gitk:2504 msgid "Tree" msgstr "Дърво" -#: gitk:2674 gitk:2695 +msgid "Unknown windowing system, cannot bind mouse" +msgstr "Непозната графична система, не може да се установи връзка с мишка" + msgid "Diff this -> selected" msgstr "Разлики между това и избраното" -#: gitk:2675 gitk:2696 msgid "Diff selected -> this" msgstr "Разлики между избраното и това" -#: gitk:2676 gitk:2697 msgid "Make patch" msgstr "Създаване на кръпка" -#: gitk:2677 gitk:9369 msgid "Create tag" msgstr "Създаване на етикет" -#: gitk:2678 msgid "Copy commit reference" msgstr "Копиране на указателя на подаване" -#: gitk:2679 gitk:9500 msgid "Write commit to file" msgstr "Запазване на подаването във файл" -#: gitk:2680 msgid "Create new branch" msgstr "Създаване на нов клон" -#: gitk:2681 msgid "Cherry-pick this commit" msgstr "Отбиране на това подаване" -#: gitk:2682 msgid "Reset HEAD branch to here" msgstr "Привеждане на върха на клона към текущото подаване" -#: gitk:2683 msgid "Mark this commit" msgstr "Отбелязване на това подаване" -#: gitk:2684 msgid "Return to mark" msgstr "Връщане към отбелязаното подаване" -#: gitk:2685 msgid "Find descendant of this and mark" msgstr "Откриване и отбелязване на наследниците" -#: gitk:2686 msgid "Compare with marked commit" msgstr "Сравнение с отбелязаното подаване" -#: gitk:2687 gitk:2698 msgid "Diff this -> marked commit" msgstr "Разлики между това и отбелязаното" -#: gitk:2688 gitk:2699 msgid "Diff marked commit -> this" msgstr "Разлики между отбелязаното и това" -#: gitk:2689 msgid "Revert this commit" msgstr "Отмяна на това подаване" -#: gitk:2705 msgid "Check out this branch" msgstr "Изтегляне на този клон" -#: gitk:2706 msgid "Rename this branch" msgstr "Преименуване на този клон" -#: gitk:2707 msgid "Remove this branch" msgstr "Изтриване на този клон" -#: gitk:2708 msgid "Copy branch name" msgstr "Копиране на името на клона" -#: gitk:2715 msgid "Highlight this too" msgstr "Отбелязване и на това" -#: gitk:2716 msgid "Highlight this only" msgstr "Отбелязване само на това" -#: gitk:2717 msgid "External diff" msgstr "Външна програма за разлики" -#: gitk:2718 msgid "Blame parent commit" msgstr "Анотиране на родителското подаване" -#: gitk:2719 msgid "Copy path" msgstr "Копиране на пътя" -#: gitk:2726 msgid "Show origin of this line" msgstr "Показване на произхода на този ред" -#: gitk:2727 msgid "Run git gui blame on this line" msgstr "Изпълнение на „git gui blame“ върху този ред" -#: gitk:3081 msgid "About gitk" msgstr "Относно gitk" -#: gitk:3083 msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -386,324 +299,250 @@ msgstr "" "\n" "Използвайте и разпространявайте при условията на ОПЛ на ГНУ" -#: gitk:3091 gitk:3158 gitk:10090 msgid "Close" msgstr "Затваряне" -#: gitk:3112 msgid "Gitk key bindings" msgstr "Клавишни комбинации" -#: gitk:3115 msgid "Gitk key bindings:" msgstr "Клавишни комбинации:" -#: gitk:3117 #, tcl-format msgid "<%s-Q>\t\tQuit" msgstr "<%s-Q>\t\tСпиране на програмата" -#: gitk:3118 #, tcl-format msgid "<%s-W>\t\tClose window" msgstr "<%s-W>\t\tЗатваряне на прозореца" -#: gitk:3119 msgid "\t\tMove to first commit" msgstr "\t\tКъм първото подаване" -#: gitk:3120 msgid "\t\tMove to last commit" msgstr "\t\tКъм последното подаване" -#: gitk:3121 msgid ", p, k\tMove up one commit" msgstr ", p, k\tЕдно подаване нагоре" -#: gitk:3122 msgid ", n, j\tMove down one commit" msgstr ", n, j\tЕдно подаване надолу" -#: gitk:3123 msgid ", z, h\tGo back in history list" msgstr ", z, h\tНазад в историята" -#: gitk:3124 msgid ", x, l\tGo forward in history list" msgstr ", x, l\tНапред в историята" -#: gitk:3125 #, tcl-format msgid "<%s-n>\tGo to n-th parent of current commit in history list" msgstr "<%s-n>\tКъм n-тия родител на текущото подаване в историята" -#: gitk:3126 msgid "\tMove up one page in commit list" msgstr "\tСтраница нагоре в списъка с подаванията" -#: gitk:3127 msgid "\tMove down one page in commit list" msgstr "\tСтраница надолу в списъка с подаванията" -#: gitk:3128 #, tcl-format msgid "<%s-Home>\tScroll to top of commit list" msgstr "<%s-Home>\tКъм началото на списъка с подаванията" -#: gitk:3129 #, tcl-format msgid "<%s-End>\tScroll to bottom of commit list" msgstr "<%s-End>\tКъм края на списъка с подаванията" -#: gitk:3130 #, tcl-format msgid "<%s-Up>\tScroll commit list up one line" msgstr "<%s-Up>\tРед нагоре в списъка с подавания" -#: gitk:3131 #, tcl-format msgid "<%s-Down>\tScroll commit list down one line" msgstr "<%s-Down>\tРед надолу в списъка с подавания" -#: gitk:3132 #, tcl-format msgid "<%s-PageUp>\tScroll commit list up one page" msgstr "<%s-PageUp>\tСтраница нагоре в списъка с подавания" -#: gitk:3133 #, tcl-format msgid "<%s-PageDown>\tScroll commit list down one page" msgstr "<%s-PageDown>\tСтраница надолу в списъка с подавания" -#: gitk:3134 msgid "\tFind backwards (upwards, later commits)" msgstr "\tТърсене назад (визуално нагоре, исторически — последващи)" -#: gitk:3135 msgid "\tFind forwards (downwards, earlier commits)" msgstr "" "\tТърсене напред (визуално надолу, исторически — предхождащи)" -#: gitk:3136 msgid ", b\tScroll diff view up one page" msgstr ", b\tСтраница нагоре в изгледа за разлики" -#: gitk:3137 msgid "\tScroll diff view up one page" msgstr "\tСтраница надолу в изгледа за разлики" -#: gitk:3138 msgid "\t\tScroll diff view down one page" msgstr "\t\tСтраница надолу в изгледа за разлики" -#: gitk:3139 msgid "u\t\tScroll diff view up 18 lines" msgstr "u\t\t18 реда нагоре в изгледа за разлики" -#: gitk:3140 msgid "d\t\tScroll diff view down 18 lines" msgstr "d\t\t18 реда надолу в изгледа за разлики" -#: gitk:3141 #, tcl-format msgid "<%s-F>\t\tFind" msgstr "<%s-F>\t\tТърсене" -#: gitk:3142 #, tcl-format msgid "<%s-G>\t\tMove to next find hit" msgstr "<%s-G>\t\tКъм следващата поява" -#: gitk:3143 msgid "\tMove to next find hit" msgstr "\tКъм следващата поява" -#: gitk:3144 msgid "g\t\tGo to commit" msgstr "g\t\tКъм последното подаване" -#: gitk:3145 msgid "/\t\tFocus the search box" msgstr "/\t\tФокус върху полето за търсене" -#: gitk:3146 msgid "?\t\tMove to previous find hit" msgstr "?\t\tКъм предишната поява" -#: gitk:3147 msgid "f\t\tScroll diff view to next file" msgstr "f\t\tСледващ файл в изгледа за разлики" -#: gitk:3148 #, tcl-format msgid "<%s-S>\t\tSearch for next hit in diff view" msgstr "<%s-S>\t\tТърсене на следващата поява в изгледа за разлики" -#: gitk:3149 #, tcl-format msgid "<%s-R>\t\tSearch for previous hit in diff view" msgstr "<%s-R>\t\tТърсене на предишната поява в изгледа за разлики" -#: gitk:3150 #, tcl-format msgid "<%s-KP+>\tIncrease font size" msgstr "<%s-KP+>\tПо-голям размер на шрифта" -#: gitk:3151 #, tcl-format msgid "<%s-plus>\tIncrease font size" msgstr "<%s-plus>\tПо-голям размер на шрифта" -#: gitk:3152 #, tcl-format msgid "<%s-KP->\tDecrease font size" msgstr "<%s-KP->\tПо-малък размер на шрифта" -#: gitk:3153 #, tcl-format msgid "<%s-minus>\tDecrease font size" msgstr "<%s-minus>\tПо-малък размер на шрифта" -#: gitk:3154 msgid "\t\tUpdate" msgstr "\t\tОбновяване" -#: gitk:3621 gitk:3630 #, tcl-format msgid "Error creating temporary directory %s:" msgstr "Грешка при създаването на временната директория „%s“:" -#: gitk:3643 #, tcl-format msgid "Error getting \"%s\" from %s:" msgstr "Грешка при получаването на „%s“ от %s:" -#: gitk:3706 msgid "command failed:" msgstr "неуспешно изпълнение на команда:" -#: gitk:3855 msgid "No such commit" msgstr "Такова подаване няма" -#: gitk:3869 msgid "git gui blame: command failed:" msgstr "„git gui blame“: неуспешно изпълнение на команда:" -#: gitk:3900 #, tcl-format msgid "Couldn't read merge head: %s" msgstr "Върхът за сливане не може да се прочете: %s" -#: gitk:3908 #, tcl-format msgid "Error reading index: %s" msgstr "Грешка при прочитане на индекса: %s" -#: gitk:3933 #, tcl-format msgid "Couldn't start git blame: %s" msgstr "Командата „git blame“ не може да се стартира: %s" -#: gitk:3936 gitk:6825 msgid "Searching" msgstr "Търсене" -#: gitk:3968 #, tcl-format msgid "Error running git blame: %s" msgstr "Грешка при изпълнението на „git blame“: %s" -#: gitk:3996 #, tcl-format msgid "That line comes from commit %s, which is not in this view" msgstr "Този ред идва от подаването %s, което не е в изгледа" -#: gitk:4010 msgid "External diff viewer failed:" msgstr "Неуспешно изпълнение на външната програма за разлики:" -#: gitk:4114 msgid "All files" msgstr "Всички файлове" -#: gitk:4138 msgid "View" msgstr "Изглед" -#: gitk:4141 msgid "Gitk view definition" msgstr "Дефиниция на изглед в Gitk" -#: gitk:4145 msgid "Remember this view" msgstr "Запазване на този изглед" -#: gitk:4146 msgid "References (space separated list):" msgstr "Указатели (списък с разделител интервал):" -#: gitk:4147 msgid "Branches & tags:" msgstr "Клони и етикети:" -#: gitk:4148 msgid "All refs" msgstr "Всички указатели" -#: gitk:4149 msgid "All (local) branches" msgstr "Всички (локални) клони" -#: gitk:4150 msgid "All tags" msgstr "Всички етикети" -#: gitk:4151 msgid "All remote-tracking branches" msgstr "Всички следящи клони" -#: gitk:4152 msgid "Commit Info (regular expressions):" msgstr "Информация за подаване (рег. изр.):" -#: gitk:4153 msgid "Author:" msgstr "Автор:" -#: gitk:4154 msgid "Committer:" msgstr "Подал:" -#: gitk:4155 msgid "Commit Message:" msgstr "Съобщение при подаване:" -#: gitk:4156 msgid "Matches all Commit Info criteria" msgstr "Съвпадение по всички характеристики на подаването" -#: gitk:4157 msgid "Matches no Commit Info criteria" msgstr "Не съвпада по никоя от характеристиките на подаването" -#: gitk:4158 msgid "Changes to Files:" msgstr "Промени по файловете:" -#: gitk:4159 msgid "Fixed String" msgstr "Дословен низ" -#: gitk:4160 msgid "Regular Expression" msgstr "Регулярен израз" -#: gitk:4161 msgid "Search string:" msgstr "Низ за търсене:" -#: gitk:4162 msgid "" "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " "15:27:38\"):" @@ -711,208 +550,159 @@ msgstr "" "Дата на подаване („2 weeks ago“ (преди 2 седмици), „2009-03-17 15:27:38“, " "„March 17, 2009 15:27:38“):" -#: gitk:4163 msgid "Since:" msgstr "От:" -#: gitk:4164 msgid "Until:" msgstr "До:" -#: gitk:4165 msgid "Limit and/or skip a number of revisions (positive integer):" msgstr "" "Ограничаване и/или прескачане на определен брой версии (неотрицателно цяло " "число):" -#: gitk:4166 msgid "Number to show:" msgstr "Брой показани:" -#: gitk:4167 msgid "Number to skip:" msgstr "Брой прескочени:" -#: gitk:4168 msgid "Miscellaneous options:" msgstr "Разни:" -#: gitk:4169 msgid "Strictly sort by date" msgstr "Подреждане по дата" -#: gitk:4170 msgid "Mark branch sides" msgstr "Отбелязване на страните по клона" -#: gitk:4171 msgid "Limit to first parent" msgstr "Само първия родител" -#: gitk:4172 msgid "Simple history" msgstr "Опростена история" -#: gitk:4173 msgid "Additional arguments to git log:" msgstr "Допълнителни аргументи към „git log“:" -#: gitk:4174 msgid "Enter files and directories to include, one per line:" msgstr "Въведете файловете и директориите за включване, по елемент на ред" -#: gitk:4175 msgid "Command to generate more commits to include:" msgstr "" "Команда за генерирането на допълнителни подавания, които да се включат:" -#: gitk:4299 msgid "Gitk: edit view" msgstr "Gitk: редактиране на изглед" -#: gitk:4307 msgid "-- criteria for selecting revisions" msgstr "— критерии за избор на версии" -#: gitk:4312 msgid "View Name" msgstr "Име на изглед" -#: gitk:4387 msgid "Apply (F5)" msgstr "Прилагане (F5)" -#: gitk:4425 msgid "Error in commit selection arguments:" msgstr "Грешка в аргументите за избор на подавания:" -#: gitk:4480 gitk:4533 gitk:4995 gitk:5009 gitk:6279 gitk:12679 gitk:12680 msgid "None" msgstr "Няма" -#: gitk:5092 gitk:5097 msgid "Descendant" msgstr "Наследник" -#: gitk:5093 msgid "Not descendant" msgstr "Не е наследник" -#: gitk:5100 gitk:5105 msgid "Ancestor" msgstr "Предшественик" -#: gitk:5101 msgid "Not ancestor" msgstr "Не е предшественик" -#: gitk:5395 msgid "Local changes checked in to index but not committed" msgstr "Локални промени добавени към индекса, но неподадени" -#: gitk:5431 msgid "Local uncommitted changes, not checked in to index" msgstr "Локални промени извън индекса" -#: gitk:7179 msgid "Error starting web browser:" msgstr "Грешка при стартирането на уеб браузър:" -#: gitk:7240 msgid "and many more" msgstr "и още много" -#: gitk:7243 msgid "many" msgstr "много" -#: gitk:7438 msgid "Tags:" msgstr "Етикети:" -#: gitk:7455 gitk:7461 gitk:8940 msgid "Parent" msgstr "Родител" -#: gitk:7466 msgid "Child" msgstr "Дете" -#: gitk:7475 msgid "Branch" msgstr "Клон" -#: gitk:7478 msgid "Follows" msgstr "Следва" -#: gitk:7481 msgid "Precedes" msgstr "Предшества" -#: gitk:8076 #, tcl-format msgid "Error getting diffs: %s" msgstr "Грешка при получаването на разликите: %s" -#: gitk:8765 msgid "Goto:" msgstr "Към ред:" -#: gitk:8786 #, tcl-format msgid "Short commit ID %s is ambiguous" msgstr "Съкратената контролна сума %s не е еднозначна" -#: gitk:8793 #, tcl-format msgid "Revision %s is not known" msgstr "Непозната версия %s" -#: gitk:8803 #, tcl-format msgid "Commit ID %s is not known" msgstr "Непозната контролна сума %s" -#: gitk:8805 #, tcl-format msgid "Revision %s is not in the current view" msgstr "Версия %s не е в текущия изглед" -#: gitk:8947 gitk:8962 msgid "Date" msgstr "Дата" -#: gitk:8950 msgid "Children" msgstr "Деца" -#: gitk:9013 #, tcl-format msgid "Reset %s branch to here" msgstr "Зануляване на клона „%s“ към текущото подаване" -#: gitk:9015 msgid "Detached head: can't reset" msgstr "Несвързан връх: невъзможно зануляване" -#: gitk:9120 gitk:9126 msgid "Skipping merge commit " msgstr "Пропускане на подаването на сливането" -#: gitk:9135 gitk:9140 msgid "Error getting patch ID for " msgstr "Грешка при получаването на идентификатора на " -#: gitk:9136 gitk:9141 msgid " - stopping\n" msgstr " — спиране\n" -#: gitk:9146 gitk:9149 gitk:9157 gitk:9171 gitk:9180 msgid "Commit " msgstr "Подаване" -#: gitk:9150 msgid "" " is the same patch as\n" " " @@ -920,7 +710,6 @@ msgstr "" " е същата кръпка като\n" " " -#: gitk:9158 msgid "" " differs from\n" " " @@ -928,7 +717,6 @@ msgstr "" " се различава от\n" " " -#: gitk:9160 msgid "" "Diff of commits:\n" "\n" @@ -936,147 +724,113 @@ msgstr "" "Разлика между подаванията:\n" "\n" -#: gitk:9172 gitk:9181 #, tcl-format msgid " has %s children - stopping\n" msgstr " има %s деца — спиране\n" -#: gitk:9200 #, tcl-format msgid "Error writing commit to file: %s" msgstr "Грешка при запазването на подаването във файл: %s" -#: gitk:9206 #, tcl-format msgid "Error diffing commits: %s" msgstr "Грешка при изчисляването на разликите между подаванията: %s" -#: gitk:9252 msgid "Top" msgstr "Най-горе" -#: gitk:9253 msgid "From" msgstr "От" -#: gitk:9258 msgid "To" msgstr "До" -#: gitk:9282 msgid "Generate patch" msgstr "Генериране на кръпка" -#: gitk:9284 msgid "From:" msgstr "От:" -#: gitk:9293 msgid "To:" msgstr "До:" -#: gitk:9302 msgid "Reverse" msgstr "Обръщане" -#: gitk:9304 gitk:9514 msgid "Output file:" msgstr "Запазване във файла:" -#: gitk:9310 msgid "Generate" msgstr "Генериране" -#: gitk:9348 msgid "Error creating patch:" msgstr "Грешка при създаването на кръпка:" -#: gitk:9371 gitk:9502 gitk:9590 msgid "ID:" msgstr "Идентификатор:" -#: gitk:9380 msgid "Tag name:" msgstr "Име на етикет:" -#: gitk:9383 msgid "Tag message is optional" msgstr "Съобщението за етикет е незадължително" -#: gitk:9385 msgid "Tag message:" msgstr "Съобщение за етикет:" -#: gitk:9389 gitk:9560 msgid "Create" msgstr "Създаване" -#: gitk:9407 msgid "No tag name specified" msgstr "Липсва име на етикет" -#: gitk:9411 #, tcl-format msgid "Tag \"%s\" already exists" msgstr "Етикетът „%s“ вече съществува" -#: gitk:9421 msgid "Error creating tag:" msgstr "Грешка при създаването на етикет:" -#: gitk:9511 msgid "Command:" msgstr "Команда:" -#: gitk:9519 msgid "Write" msgstr "Запазване" -#: gitk:9537 msgid "Error writing commit:" msgstr "Грешка при запазването на подаването:" -#: gitk:9559 msgid "Create branch" msgstr "Създаване на клон" -#: gitk:9575 #, tcl-format msgid "Rename branch %s" msgstr "Преименуване на клона „%s“" -#: gitk:9576 msgid "Rename" msgstr "Преименуване" -#: gitk:9600 msgid "Name:" msgstr "Име:" -#: gitk:9624 msgid "Please specify a name for the new branch" msgstr "Укажете име за новия клон" -#: gitk:9629 #, tcl-format msgid "Branch '%s' already exists. Overwrite?" msgstr "Клонът „%s“ вече съществува. Да се презапише ли?" -#: gitk:9673 msgid "Please specify a new name for the branch" msgstr "Укажете ново име за клона" -#: gitk:9736 #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" "Подаването „%s“ вече е включено в клона „%s“ — да се приложи ли отново?" -#: gitk:9741 msgid "Cherry-picking" msgstr "Отбиране" -#: gitk:9750 #, tcl-format msgid "" "Cherry-pick failed because of local changes to file '%s'.\n" @@ -1085,7 +839,6 @@ msgstr "" "Неуспешно отбиране, защото във файла „%s“ има локални промени.\n" "Подайте, занулете или ги скатайте и пробвайте отново." -#: gitk:9756 msgid "" "Cherry-pick failed because of merge conflict.\n" "Do you wish to run git citool to resolve it?" @@ -1093,20 +846,16 @@ msgstr "" "Неуспешно отбиране поради конфликти при сливане.\n" "Искате ли да ги коригирате чрез „git citool“?" -#: gitk:9772 gitk:9830 msgid "No changes committed" msgstr "Не са подадени промени" -#: gitk:9799 #, tcl-format msgid "Commit %s is not included in branch %s -- really revert it?" msgstr "Подаването „%s“ не е включено в клона „%s“. Да се отменени ли?" -#: gitk:9804 msgid "Reverting" msgstr "Отмяна" -#: gitk:9812 #, tcl-format msgid "" "Revert failed because of local changes to the following files:%s Please " @@ -1115,7 +864,6 @@ msgstr "" "Неуспешна отмяна, защото във файла „%s“ има локални промени.\n" "Подайте, занулете или ги скатайте и пробвайте отново." -#: gitk:9816 msgid "" "Revert failed because of merge conflict.\n" " Do you wish to run git citool to resolve it?" @@ -1123,28 +871,22 @@ msgstr "" "Неуспешно отмяна поради конфликти при сливане.\n" "Искате ли да ги коригирате чрез „git citool“?" -#: gitk:9859 msgid "Confirm reset" msgstr "Потвърждаване на зануляването" -#: gitk:9861 #, tcl-format msgid "Reset branch %s to %s?" msgstr "Да се занули ли клонът „%s“ към „%s“?" -#: gitk:9863 msgid "Reset type:" msgstr "Вид зануляване:" -#: gitk:9866 msgid "Soft: Leave working tree and index untouched" msgstr "Слабо: работното дърво и индекса остават същите" -#: gitk:9869 msgid "Mixed: Leave working tree untouched, reset index" msgstr "Смесено: работното дърво остава същото, индексът се занулява" -#: gitk:9872 msgid "" "Hard: Reset working tree and index\n" "(discard ALL local changes)" @@ -1152,24 +894,19 @@ msgstr "" "Силно: зануляване и на работното дърво, и на индекса\n" "(ВСИЧКИ локални промени ще се загубят безвъзвратно)" -#: gitk:9889 msgid "Resetting" msgstr "Зануляване" -#: gitk:9962 #, tcl-format msgid "A local branch named %s exists already" msgstr "Вече съществува локален клон „%s“." -#: gitk:9970 msgid "Checking out" msgstr "Изтегляне" -#: gitk:10029 msgid "Cannot delete the currently checked-out branch" msgstr "Текущо изтегленият клон не може да се изтрие" -#: gitk:10035 #, tcl-format msgid "" "The commits on branch %s aren't on any other branch.\n" @@ -1178,16 +915,16 @@ msgstr "" "Подаванията на клона „%s“ не са на никой друг клон.\n" "Наистина ли искате да изтриете клона „%s“?" -#: gitk:10066 #, tcl-format msgid "Tags and heads: %s" msgstr "Етикети и върхове: %s" -#: gitk:10083 msgid "Filter" msgstr "Филтриране" -#: gitk:10390 +msgid "Sort refs by type" +msgstr "Подредба на указателите по вид" + msgid "" "Error reading commit topology information; branch and preceding/following " "tag information will be incomplete." @@ -1195,253 +932,167 @@ msgstr "" "Грешка при прочитането на топологията на подаванията. Информацията за клона " "и предшестващите/следващите етикети ще е непълна." -#: gitk:11367 msgid "Tag" msgstr "Етикет" -#: gitk:11371 msgid "Id" msgstr "Идентификатор" -#: gitk:11454 -msgid "Gitk font chooser" -msgstr "Избор на шрифт за Gitk" - -#: gitk:11471 -msgid "B" -msgstr "Ч" - -#: gitk:11474 -msgid "I" -msgstr "К" - -#: gitk:11593 msgid "Commit list display options" msgstr "Настройки на списъка с подавания" -#: gitk:11596 msgid "Maximum graph width (lines)" msgstr "Максимална широчина на графа (в редове)" -#: gitk:11600 #, no-tcl-format msgid "Maximum graph width (% of pane)" msgstr "Максимална широчина на графа (% от панела)" -#: gitk:11603 msgid "Show local changes" msgstr "Показване на локалните промени" -#: gitk:11606 msgid "Hide remote refs" msgstr "Скриване на отдалечените указатели" -#: gitk:11610 msgid "Copy commit ID to clipboard" msgstr "Копиране на контролната сума към буфера за обмен" -#: gitk:11614 msgid "Copy commit ID to X11 selection" msgstr "Копиране на контролната сума в селекцията на X11" -#: gitk:11619 msgid "Length of commit ID to copy" msgstr "Дължина на контролната сума, която се копира" -#: gitk:11622 +msgid "Wheel scrolling multiplier" +msgstr "Множител за колелцето на мишката" + msgid "Diff display options" msgstr "Настройки на показването на разликите" -#: gitk:11624 msgid "Tab spacing" msgstr "Широчина на табулатора" -#: gitk:11628 msgid "Wrap comment text" msgstr "Пренасяне на думите в коментарите" -#: gitk:11633 msgid "Wrap other text" msgstr "Пренасяне на другия текст" -#: gitk:11638 msgid "Display nearby tags/heads" msgstr "Извеждане на близките етикети и върхове" -#: gitk:11641 msgid "Maximum # tags/heads to show" msgstr "Максимален брой етикети/върхове за показване" -#: gitk:11644 msgid "Limit diffs to listed paths" msgstr "Разлика само в избраните пътища" -#: gitk:11647 msgid "Support per-file encodings" msgstr "Поддръжка на различни кодирания за всеки файл" -#: gitk:11653 gitk:11820 msgid "External diff tool" msgstr "Външен инструмент за разлики" -#: gitk:11654 msgid "Choose..." msgstr "Избор…" -#: gitk:11661 msgid "Web browser" msgstr "Уеб браузър" -#: gitk:11666 -msgid "General options" -msgstr "Общи настройки" - -#: gitk:11669 -msgid "Use themed widgets" -msgstr "Използване на тема за графичните обекти" - -#: gitk:11671 -msgid "(change requires restart)" -msgstr "(промяната изисква рестартиране на Gitk)" - -#: gitk:11673 -msgid "(currently unavailable)" -msgstr "(в момента недостъпно)" - -#: gitk:11685 msgid "Colors: press to choose" msgstr "Цветове: избира се с натискане" -#: gitk:11688 msgid "Interface" msgstr "Интерфейс" -#: gitk:11689 msgid "interface" msgstr "интерфейс" -#: gitk:11692 msgid "Background" msgstr "Фон" -#: gitk:11693 gitk:11735 msgid "background" msgstr "фон" -#: gitk:11696 msgid "Foreground" msgstr "Знаци" -#: gitk:11697 msgid "foreground" msgstr "знаци" -#: gitk:11700 msgid "Diff: old lines" msgstr "Разлика: стари редове" -#: gitk:11701 msgid "diff old lines" msgstr "разлика, стари редове" -#: gitk:11705 msgid "Diff: old lines bg" msgstr "Разлика: фон на стари редове" -#: gitk:11707 msgid "diff old lines bg" msgstr "разлика, фон на стари редове" -#: gitk:11711 msgid "Diff: new lines" msgstr "Разлика: нови редове" -#: gitk:11712 msgid "diff new lines" msgstr "разлика, нови редове" -#: gitk:11716 msgid "Diff: new lines bg" msgstr "Разлика: фон на нови редове" -#: gitk:11718 msgid "diff new lines bg" msgstr "разлика, фон на нови редове" -#: gitk:11722 msgid "Diff: hunk header" msgstr "Разлика: начало на парче" -#: gitk:11724 msgid "diff hunk header" msgstr "разлика, начало на парче" -#: gitk:11728 msgid "Marked line bg" msgstr "Фон на отбелязан ред" -#: gitk:11730 msgid "marked line background" msgstr "фон на отбелязан ред" -#: gitk:11734 msgid "Select bg" msgstr "Избор на фон" -#: gitk:11743 msgid "Fonts: press to choose" msgstr "Шрифтове: избира се с натискане" -#: gitk:11745 msgid "Main font" msgstr "Основен шрифт" -#: gitk:11746 msgid "Diff display font" msgstr "Шрифт за разликите" -#: gitk:11747 msgid "User interface font" msgstr "Шрифт на интерфейса" -#: gitk:11769 msgid "Gitk preferences" msgstr "Настройки на Gitk" -#: gitk:11778 msgid "General" msgstr "Общи" -#: gitk:11779 msgid "Colors" msgstr "Цветове" -#: gitk:11780 msgid "Fonts" msgstr "Шрифтове" -#: gitk:11830 #, tcl-format msgid "Gitk: choose color for %s" msgstr "Gitk: избор на цвят на „%s“" -#: gitk:12350 -msgid "" -"Sorry, gitk cannot run with this version of Tcl/Tk.\n" -" Gitk requires at least Tcl/Tk 8.4." -msgstr "" -"Тази версия на Tcl/Tk не се поддържа от Gitk.\n" -" Необходима ви е поне Tcl/Tk 8.4." - -#: gitk:12571 msgid "Cannot find a git repository here." msgstr "Тук липсва хранилище на Git." -#: gitk:12618 #, tcl-format msgid "Ambiguous argument '%s': both revision and filename" msgstr "Нееднозначен аргумент „%s“: има и такава версия, и такъв файл" -#: gitk:12630 msgid "Bad arguments to gitk:" msgstr "Неправилни аргументи на gitk:" diff --git a/http.c b/http.c index 7731c3697781e4..361c8ba5948f69 100644 --- a/http.c +++ b/http.c @@ -2368,7 +2368,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); @@ -2852,7 +2852,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; diff --git a/loose.c b/loose.c index 519f5db79352a1..e8ea6e7e24ba31 100644 --- a/loose.c +++ b/loose.c @@ -166,7 +166,8 @@ int repo_write_loose_object_map(struct repository *repo) 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 @@ static int write_one_object(struct repository *repo, const struct object_id *oid 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; } diff --git a/loose.h b/loose.h index 28512306e5fec7..6af1702973c058 100644 --- a/loose.h +++ b/loose.h @@ -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 5a8a5c39b04ab9..4216933d06b163 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 86896ff11b014d..cd0cb4d1f07d2d 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 c1ae62d3549425..a0aceab5e0d1ac 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 dd56feed6e8cfe..bf5bb1f6c13a13 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); } diff --git a/notes.c b/notes.c index 49393fbfd8d860..9736276f376a20 100644 --- a/notes.c +++ b/notes.c @@ -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 7c3146dfdca5f0..10ca56e56248d3 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 @@ static int check_collision(const char *source, const char *dest) /* * 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 @@ int finalize_object_file_flags(const char *tmpfile, const char *filename, } 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, size_t 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, size_t 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]; size_t hdrlen = sizeof(hdr); @@ -1069,7 +1055,7 @@ int write_object_file_flags(const void *buf, size_t 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, size_t 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 : ""); - else if (read_result != size) + else if ((size_t) read_result != size) ret = error(_("short read while indexing %s"), path ? path : ""); 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 a001cc7587ce38..dc24393a9ebe1c 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, size_t 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, size_t 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, diff --git a/odb.c b/odb.c index 1f48a0448e398a..2a92a018c42940 100644 --- a/odb.c +++ b/odb.c @@ -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)); diff --git a/odb.h b/odb.h index 09177bf430dc38..3dfc66d75a3d20 100644 --- a/odb.h +++ b/odb.h @@ -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 eccdc798e368c3..83eaf88541eefb 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); diff --git a/pack.h b/pack.h index 5d4393eaffef04..ec76472e49b052 100644 --- a/pack.h +++ b/pack.h @@ -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 92fb4fbb0ed3d1..d49dc11957c7a6 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 8330a14fa82b96..22266db5233df7 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 d4cca9e4d63f0a..817d6edade55c9 100644 --- a/read-cache.c +++ b/read-cache.c @@ -701,7 +701,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 d6a501d4535417..fd3e7e355e4ffc 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 9509dc18fde909..6fd3b870dec777 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/t/unit-tests/clar/clar.c b/t/unit-tests/clar/clar.c index d54e4553674908..03a3aa8e873bfc 100644 --- a/t/unit-tests/clar/clar.c +++ b/t/unit-tests/clar/clar.c @@ -350,7 +350,7 @@ static void clar_run_suite(const struct clar_suite *suite, const char *filter) { const struct clar_func *test = suite->tests; - size_t i, matchlen; + size_t i, matchlen = 0; struct clar_report *report; int exact = 0; diff --git a/tmp-objdir.c b/tmp-objdir.c index ae01eae9c415d3..9f5a1788cd7c48 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)