From ce83ab2bd3751eadb0eb6f12d1e9d984613a4cc2 Mon Sep 17 00:00:00 2001 From: Pratyush Yadav Date: Fri, 27 Nov 2020 15:53:51 +0530 Subject: [PATCH 01/42] git-gui: Only touch GITGUI_MSG when needed In 4e55d19 (git-gui: Cleanup end-of-line whitespace in commit messages., 2007-01-25), the logic to decide if GITGUI_MSG should be saved or deleted was updated to not require the commit message buffer to be modified. This fixes a situation where if the user quits and restarts git-gui multiple times the commit message buffer was lost. Unfortunately, the fix was not quite correct. The check for whether the commit message buffer has been modified is useless. If the commit is _not_ amend, then the check is never performed. If the commit is amend, then saving the message does not matter anyway. Amend state is destroyed on exit and the next time git-gui is opened it starts from scratch, but with the older message retained in the buffer. If amend is selected, the current message is over-written by the amend commit's message. The correct fix would be to not touch GITGUI_MSG at all if the commit message buffer is not modified. This way, the file is not deleted even on multiple restarts. It has the added benefit of not writing the file unnecessarily on every exit. Signed-off-by: Pratyush Yadav --- git-gui.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 867b8cea46..8ee67e6f09 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -2305,11 +2305,10 @@ proc do_quit {{rc {1}}} { if {$GITGUI_BCK_exists && ![$ui_comm edit modified]} { file rename -force [gitdir GITGUI_BCK] $save set GITGUI_BCK_exists 0 - } else { + } elseif {[$ui_comm edit modified]} { set msg [string trim [$ui_comm get 0.0 end]] regsub -all -line {[ \r\t]+$} $msg {} msg - if {(![string match amend* $commit_type] - || [$ui_comm edit modified]) + if {![string match amend* $commit_type] && $msg ne {}} { catch { set fd [open $save w] From 627c87f84c157885d587125cf0c73591a0e3ee7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sch=C3=B6n?= Date: Mon, 2 Jul 2018 15:28:09 +0200 Subject: [PATCH 02/42] git-gui: use commit message template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the file described by commit.template (if set) to show the commit message template, just like other GUIs. Signed-off-by: Martin Schön Signed-off-by: Pratyush Yadav --- git-gui.sh | 7 +++++++ lib/commit.tcl | 1 + 2 files changed, 8 insertions(+) diff --git a/git-gui.sh b/git-gui.sh index 8ee67e6f09..cc6c2aa2c3 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1482,6 +1482,7 @@ proc rescan {after {honor_trustmtime 1}} { } elseif {[run_prepare_commit_msg_hook]} { } elseif {[load_message MERGE_MSG]} { } elseif {[load_message SQUASH_MSG]} { + } elseif {[load_message [get_config commit.template]]} { } $ui_comm edit reset $ui_comm edit modified false @@ -1616,6 +1617,12 @@ proc run_prepare_commit_msg_hook {} { fconfigure $fd_sm -encoding utf-8 puts -nonewline $fd_pcm [read $fd_sm] close $fd_sm + } elseif {[file isfile [get_config commit.template]]} { + set pcm_source "template" + set fd_sm [open [get_config commit.template] r] + fconfigure $fd_sm -encoding utf-8 + puts -nonewline $fd_pcm [read $fd_sm] + close $fd_sm } else { set pcm_source "" } diff --git a/lib/commit.tcl b/lib/commit.tcl index b516aa2990..11379f8ad3 100644 --- a/lib/commit.tcl +++ b/lib/commit.tcl @@ -456,6 +456,7 @@ A rescan will be automatically started now. } $ui_comm delete 0.0 end + load_message [get_config commit.template] $ui_comm edit reset $ui_comm edit modified false if {$::GITGUI_BCK_exists} { From 3d02fb242cf094e4a374f2fa8332ec1834bdcc21 Mon Sep 17 00:00:00 2001 From: Dimitriy Ryazantcev Date: Fri, 6 Nov 2020 20:49:04 +0200 Subject: [PATCH 03/42] git-gui: update Russian translation Translation is done on Transifex: https://www.transifex.com/djm00n/git-po-ru/git-gui/ If you have any corrections please report them there. Signed-off-by: Dimitriy Ryazantcev Signed-off-by: Pratyush Yadav --- po/ru.po | 3363 +++++++++++++++++++++++++++++------------------------- 1 file changed, 1816 insertions(+), 1547 deletions(-) diff --git a/po/ru.po b/po/ru.po index 9f5305c43e..161ee1ac8c 100644 --- a/po/ru.po +++ b/po/ru.po @@ -2,14 +2,14 @@ # Copyright (C) 2007 Shawn Pearce # This file is distributed under the same license as the git-gui package. # Translators: -# Dimitriy Ryazantcev , 2015-2016 +# Dimitriy Ryazantcev , 2015-2016,2020 # Irina Riesen , 2007 msgid "" msgstr "" "Project-Id-Version: Git Russian Localization Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-01-26 15:47-0800\n" -"PO-Revision-Date: 2016-06-30 12:39+0000\n" +"POT-Creation-Date: 2020-02-08 22:54+0100\n" +"PO-Revision-Date: 2020-11-05 11:20+0000\n" "Last-Translator: Dimitriy Ryazantcev \n" "Language-Team: Russian (http://www.transifex.com/djm00n/git-po-ru/language/ru/)\n" "MIME-Version: 1.0\n" @@ -18,33 +18,33 @@ msgstr "" "Language: ru\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" -#: git-gui.sh:41 git-gui.sh:793 git-gui.sh:807 git-gui.sh:820 git-gui.sh:903 -#: git-gui.sh:922 -msgid "git-gui: fatal error" -msgstr "git-gui: критическая ошибка" - -#: git-gui.sh:743 +#: git-gui.sh:847 #, tcl-format msgid "Invalid font specified in %s:" msgstr "В %s установлен неверный шрифт:" -#: git-gui.sh:779 +#: git-gui.sh:901 msgid "Main Font" msgstr "Шрифт интерфейса" -#: git-gui.sh:780 +#: git-gui.sh:902 msgid "Diff/Console Font" msgstr "Шрифт консоли и изменений (diff)" -#: git-gui.sh:794 +#: git-gui.sh:917 git-gui.sh:931 git-gui.sh:944 git-gui.sh:1034 +#: git-gui.sh:1053 git-gui.sh:3212 +msgid "git-gui: fatal error" +msgstr "git-gui: критическая ошибка" + +#: git-gui.sh:918 msgid "Cannot find git in PATH." msgstr "git не найден в PATH." -#: git-gui.sh:821 +#: git-gui.sh:945 msgid "Cannot parse Git version string:" msgstr "Невозможно распознать строку версии Git: " -#: git-gui.sh:839 +#: git-gui.sh:970 #, tcl-format msgid "" "Git version cannot be determined.\n" @@ -56,473 +56,519 @@ msgid "" "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" -#: git-gui.sh:1128 +#: git-gui.sh:1267 msgid "Git directory not found:" msgstr "Каталог Git не найден:" -#: git-gui.sh:1146 +#: git-gui.sh:1301 msgid "Cannot move to top of working directory:" msgstr "Невозможно перейти к корню рабочего каталога репозитория: " -#: git-gui.sh:1154 +#: git-gui.sh:1309 msgid "Cannot use bare repository:" msgstr "Невозможно использование репозитория без рабочего каталога:" -#: git-gui.sh:1162 +#: git-gui.sh:1317 msgid "No working directory" msgstr "Отсутствует рабочий каталог" -#: git-gui.sh:1334 lib/checkout_op.tcl:306 +#: git-gui.sh:1491 lib/checkout_op.tcl:306 msgid "Refreshing file status..." msgstr "Обновление информации о состоянии файлов…" -#: git-gui.sh:1390 +#: git-gui.sh:1551 msgid "Scanning for modified files ..." msgstr "Поиск измененных файлов…" -#: git-gui.sh:1454 +#: git-gui.sh:1629 msgid "Calling prepare-commit-msg hook..." msgstr "Вызов перехватчика prepare-commit-msg…" -#: git-gui.sh:1471 +#: git-gui.sh:1646 msgid "Commit declined by prepare-commit-msg hook." msgstr "Коммит прерван перехватчиком prepare-commit-msg." -#: git-gui.sh:1629 lib/browser.tcl:246 +#: git-gui.sh:1804 lib/browser.tcl:252 msgid "Ready." msgstr "Готово." -#: git-gui.sh:1787 +#: git-gui.sh:1968 #, tcl-format -msgid "Displaying only %s of %s files." -msgstr "Показано %s из %s файлов." +msgid "" +"Display limit (gui.maxfilesdisplayed = %s) reached, not showing all %s " +"files." +msgstr "Лимит отображаемых файлов достигнут (gui.maxfilesdisplayed = %s), не все %s файлы показаны." -#: git-gui.sh:1913 +#: git-gui.sh:2091 msgid "Unmodified" msgstr "Не изменено" -#: git-gui.sh:1915 +#: git-gui.sh:2093 msgid "Modified, not staged" msgstr "Изменено, не в индексе" -#: git-gui.sh:1916 git-gui.sh:1924 +#: git-gui.sh:2094 git-gui.sh:2106 msgid "Staged for commit" msgstr "В индексе для коммита" -#: git-gui.sh:1917 git-gui.sh:1925 +#: git-gui.sh:2095 git-gui.sh:2107 msgid "Portions staged for commit" msgstr "Части, в индексе для коммита" -#: git-gui.sh:1918 git-gui.sh:1926 +#: git-gui.sh:2096 git-gui.sh:2108 msgid "Staged for commit, missing" msgstr "В индексе для коммита, отсутствует" -#: git-gui.sh:1920 +#: git-gui.sh:2098 msgid "File type changed, not staged" msgstr "Тип файла изменён, не в индексе" -#: git-gui.sh:1921 +#: git-gui.sh:2099 git-gui.sh:2100 +msgid "File type changed, old type staged for commit" +msgstr "Тип файла изменён, старый тип файла в индексе" + +#: git-gui.sh:2101 msgid "File type changed, staged" msgstr "Тип файла изменён, в индексе" -#: git-gui.sh:1923 +#: git-gui.sh:2102 +msgid "File type change staged, modification not staged" +msgstr "Изменение типа файла в индексе, изменение не в индексе" + +#: git-gui.sh:2103 +msgid "File type change staged, file missing" +msgstr "Изменение типа файла в индексе, файл не найден" + +#: git-gui.sh:2105 msgid "Untracked, not staged" msgstr "Не отслеживается, не в индексе" -#: git-gui.sh:1928 +#: git-gui.sh:2110 msgid "Missing" msgstr "Отсутствует" -#: git-gui.sh:1929 +#: git-gui.sh:2111 msgid "Staged for removal" msgstr "В индексе для удаления" -#: git-gui.sh:1930 +#: git-gui.sh:2112 msgid "Staged for removal, still present" msgstr "В индексе для удаления, еще не удалено" -#: git-gui.sh:1932 git-gui.sh:1933 git-gui.sh:1934 git-gui.sh:1935 -#: git-gui.sh:1936 git-gui.sh:1937 +#: git-gui.sh:2114 git-gui.sh:2115 git-gui.sh:2116 git-gui.sh:2117 +#: git-gui.sh:2118 git-gui.sh:2119 msgid "Requires merge resolution" msgstr "Требуется разрешение конфликта при слиянии" -#: git-gui.sh:1972 -msgid "Starting gitk... please wait..." -msgstr "Запускается gitk… Подождите, пожалуйста…" - -#: git-gui.sh:1984 +#: git-gui.sh:2164 msgid "Couldn't find gitk in PATH" msgstr "gitk не найден в PATH." -#: git-gui.sh:2043 +#: git-gui.sh:2210 git-gui.sh:2245 +#, tcl-format +msgid "Starting %s... please wait..." +msgstr "Запускается %s… Подождите, пожалуйста…" + +#: git-gui.sh:2224 msgid "Couldn't find git gui in PATH" msgstr "git gui не найден в PATH." -#: git-gui.sh:2455 lib/choose_repository.tcl:36 +#: git-gui.sh:2726 lib/choose_repository.tcl:53 msgid "Repository" msgstr "Репозиторий" -#: git-gui.sh:2456 +#: git-gui.sh:2727 msgid "Edit" -msgstr "Редактировать" +msgstr "Правка" -#: git-gui.sh:2458 lib/choose_rev.tcl:561 +#: git-gui.sh:2729 lib/choose_rev.tcl:567 msgid "Branch" msgstr "Ветка" -#: git-gui.sh:2461 lib/choose_rev.tcl:548 +#: git-gui.sh:2732 lib/choose_rev.tcl:554 msgid "Commit@@noun" msgstr "Коммит" -#: git-gui.sh:2464 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 +#: git-gui.sh:2735 lib/merge.tcl:127 lib/merge.tcl:174 msgid "Merge" msgstr "Слияние" -#: git-gui.sh:2465 lib/choose_rev.tcl:557 +#: git-gui.sh:2736 lib/choose_rev.tcl:563 msgid "Remote" msgstr "Внешние репозитории" -#: git-gui.sh:2468 +#: git-gui.sh:2739 msgid "Tools" msgstr "Вспомогательные операции" -#: git-gui.sh:2477 +#: git-gui.sh:2748 msgid "Explore Working Copy" msgstr "Просмотр рабочего каталога" -#: git-gui.sh:2483 +#: git-gui.sh:2763 +msgid "Git Bash" +msgstr "Git Bash" + +#: git-gui.sh:2772 msgid "Browse Current Branch's Files" msgstr "Просмотреть файлы текущей ветки" -#: git-gui.sh:2487 +#: git-gui.sh:2776 msgid "Browse Branch Files..." msgstr "Показать файлы ветки…" -#: git-gui.sh:2492 +#: git-gui.sh:2781 msgid "Visualize Current Branch's History" msgstr "Показать историю текущей ветки" -#: git-gui.sh:2496 +#: git-gui.sh:2785 msgid "Visualize All Branch History" msgstr "Показать историю всех веток" -#: git-gui.sh:2503 +#: git-gui.sh:2792 #, tcl-format msgid "Browse %s's Files" msgstr "Показать файлы ветки %s" -#: git-gui.sh:2505 +#: git-gui.sh:2794 #, tcl-format msgid "Visualize %s's History" msgstr "Показать историю ветки %s" -#: git-gui.sh:2510 lib/database.tcl:27 lib/database.tcl:67 +#: git-gui.sh:2799 lib/database.tcl:40 msgid "Database Statistics" msgstr "Статистика базы данных" -#: git-gui.sh:2513 lib/database.tcl:34 +#: git-gui.sh:2802 lib/database.tcl:33 msgid "Compress Database" msgstr "Сжать базу данных" -#: git-gui.sh:2516 +#: git-gui.sh:2805 msgid "Verify Database" msgstr "Проверить базу данных" -#: git-gui.sh:2523 git-gui.sh:2527 git-gui.sh:2531 lib/shortcut.tcl:8 -#: lib/shortcut.tcl:40 lib/shortcut.tcl:72 +#: git-gui.sh:2812 git-gui.sh:2816 git-gui.sh:2820 msgid "Create Desktop Icon" msgstr "Создать ярлык на рабочем столе" -#: git-gui.sh:2539 lib/choose_repository.tcl:183 lib/choose_repository.tcl:191 +#: git-gui.sh:2828 lib/choose_repository.tcl:209 lib/choose_repository.tcl:217 msgid "Quit" msgstr "Выход" -#: git-gui.sh:2547 +#: git-gui.sh:2836 msgid "Undo" msgstr "Отменить" -#: git-gui.sh:2550 +#: git-gui.sh:2839 msgid "Redo" msgstr "Повторить" -#: git-gui.sh:2554 git-gui.sh:3109 +#: git-gui.sh:2843 git-gui.sh:3461 msgid "Cut" msgstr "Вырезать" -#: git-gui.sh:2557 git-gui.sh:3112 git-gui.sh:3186 git-gui.sh:3259 +#: git-gui.sh:2846 git-gui.sh:3464 git-gui.sh:3540 git-gui.sh:3633 #: lib/console.tcl:69 msgid "Copy" msgstr "Копировать" -#: git-gui.sh:2560 git-gui.sh:3115 +#: git-gui.sh:2849 git-gui.sh:3467 msgid "Paste" msgstr "Вставить" -#: git-gui.sh:2563 git-gui.sh:3118 lib/branch_delete.tcl:26 -#: lib/remote_branch_delete.tcl:38 +#: git-gui.sh:2852 git-gui.sh:3470 lib/remote_branch_delete.tcl:39 +#: lib/branch_delete.tcl:28 msgid "Delete" msgstr "Удалить" -#: git-gui.sh:2567 git-gui.sh:3122 git-gui.sh:3263 lib/console.tcl:71 +#: git-gui.sh:2856 git-gui.sh:3474 git-gui.sh:3637 lib/console.tcl:71 msgid "Select All" -msgstr "Выделить все" +msgstr "Выделить всё" -#: git-gui.sh:2576 +#: git-gui.sh:2865 msgid "Create..." msgstr "Создать…" -#: git-gui.sh:2582 +#: git-gui.sh:2871 msgid "Checkout..." msgstr "Перейти…" -#: git-gui.sh:2588 +#: git-gui.sh:2877 msgid "Rename..." msgstr "Переименовать…" -#: git-gui.sh:2593 +#: git-gui.sh:2882 msgid "Delete..." msgstr "Удалить…" -#: git-gui.sh:2598 +#: git-gui.sh:2887 msgid "Reset..." msgstr "Сбросить…" -#: git-gui.sh:2608 +#: git-gui.sh:2897 msgid "Done" msgstr "Завершено" -#: git-gui.sh:2610 +#: git-gui.sh:2899 msgid "Commit@@verb" msgstr "Закоммитить" -#: git-gui.sh:2619 git-gui.sh:3050 -msgid "New Commit" -msgstr "Новый коммит" - -#: git-gui.sh:2627 git-gui.sh:3057 +#: git-gui.sh:2908 git-gui.sh:3400 msgid "Amend Last Commit" msgstr "Исправить последний коммит" -#: git-gui.sh:2637 git-gui.sh:3011 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:2918 git-gui.sh:3361 lib/remote_branch_delete.tcl:101 msgid "Rescan" msgstr "Перечитать" -#: git-gui.sh:2643 +#: git-gui.sh:2924 msgid "Stage To Commit" msgstr "Добавить в индекс" -#: git-gui.sh:2649 +#: git-gui.sh:2930 msgid "Stage Changed Files To Commit" msgstr "Добавить изменённые файлы в индекс" -#: git-gui.sh:2655 +#: git-gui.sh:2936 msgid "Unstage From Commit" msgstr "Убрать из издекса" -#: git-gui.sh:2661 lib/index.tcl:412 +#: git-gui.sh:2942 lib/index.tcl:521 msgid "Revert Changes" msgstr "Обратить изменения" -#: git-gui.sh:2669 git-gui.sh:3310 git-gui.sh:3341 +#: git-gui.sh:2950 git-gui.sh:3700 git-gui.sh:3731 msgid "Show Less Context" msgstr "Меньше контекста" -#: git-gui.sh:2673 git-gui.sh:3314 git-gui.sh:3345 +#: git-gui.sh:2954 git-gui.sh:3704 git-gui.sh:3735 msgid "Show More Context" msgstr "Больше контекста" -#: git-gui.sh:2680 git-gui.sh:3024 git-gui.sh:3133 +#: git-gui.sh:2961 git-gui.sh:3374 git-gui.sh:3485 msgid "Sign Off" msgstr "Вставить Signed-off-by" -#: git-gui.sh:2696 +#: git-gui.sh:2977 msgid "Local Merge..." msgstr "Локальное слияние…" -#: git-gui.sh:2701 +#: git-gui.sh:2982 msgid "Abort Merge..." msgstr "Прервать слияние…" -#: git-gui.sh:2713 git-gui.sh:2741 +#: git-gui.sh:2994 git-gui.sh:3022 msgid "Add..." msgstr "Добавить…" -#: git-gui.sh:2717 +#: git-gui.sh:2998 msgid "Push..." msgstr "Отправить…" -#: git-gui.sh:2721 +#: git-gui.sh:3002 msgid "Delete Branch..." msgstr "Удалить ветку…" -#: git-gui.sh:2731 git-gui.sh:3292 +#: git-gui.sh:3012 git-gui.sh:3666 msgid "Options..." msgstr "Настройки…" -#: git-gui.sh:2742 +#: git-gui.sh:3023 msgid "Remove..." msgstr "Удалить…" -#: git-gui.sh:2751 lib/choose_repository.tcl:50 +#: git-gui.sh:3032 lib/choose_repository.tcl:67 msgid "Help" -msgstr "Помощь" +msgstr "Справка" -#: git-gui.sh:2755 git-gui.sh:2759 lib/about.tcl:14 -#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:53 +#: git-gui.sh:3036 git-gui.sh:3040 lib/choose_repository.tcl:61 +#: lib/choose_repository.tcl:70 lib/about.tcl:14 #, tcl-format msgid "About %s" msgstr "О %s" -#: git-gui.sh:2783 +#: git-gui.sh:3064 msgid "Online Documentation" msgstr "Документация в интернете" -#: git-gui.sh:2786 lib/choose_repository.tcl:47 lib/choose_repository.tcl:56 +#: git-gui.sh:3067 lib/choose_repository.tcl:64 lib/choose_repository.tcl:73 msgid "Show SSH Key" msgstr "Показать ключ SSH" -#: git-gui.sh:2893 +#: git-gui.sh:3097 git-gui.sh:3229 +msgid "usage:" +msgstr "использование:" + +#: git-gui.sh:3101 git-gui.sh:3233 +msgid "Usage" +msgstr "Использование" + +#: git-gui.sh:3182 lib/blame.tcl:575 +msgid "Error" +msgstr "Ошибка" + +#: git-gui.sh:3213 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "критическая ошибка: %s: нет такого файла или каталога" -#: git-gui.sh:2926 +#: git-gui.sh:3246 msgid "Current Branch:" msgstr "Текущая ветка:" -#: git-gui.sh:2947 -msgid "Staged Changes (Will Commit)" -msgstr "Изменения в индексе (будут закоммичены)" - -#: git-gui.sh:2967 +#: git-gui.sh:3271 msgid "Unstaged Changes" msgstr "Изменено (не будет сохранено)" -#: git-gui.sh:3017 +#: git-gui.sh:3293 +msgid "Staged Changes (Will Commit)" +msgstr "Изменения в индексе (будут закоммичены)" + +#: git-gui.sh:3367 msgid "Stage Changed" msgstr "Индексировать всё" -#: git-gui.sh:3036 lib/transport.tcl:104 lib/transport.tcl:193 +#: git-gui.sh:3386 lib/transport.tcl:137 msgid "Push" msgstr "Отправить" -#: git-gui.sh:3071 +#: git-gui.sh:3413 msgid "Initial Commit Message:" msgstr "Сообщение первого коммита:" -#: git-gui.sh:3072 +#: git-gui.sh:3414 msgid "Amended Commit Message:" msgstr "Сообщение исправленного коммита:" -#: git-gui.sh:3073 +#: git-gui.sh:3415 msgid "Amended Initial Commit Message:" msgstr "Сообщение исправленного первого коммита:" -#: git-gui.sh:3074 +#: git-gui.sh:3416 msgid "Amended Merge Commit Message:" msgstr "Сообщение исправленного слияния:" -#: git-gui.sh:3075 +#: git-gui.sh:3417 msgid "Merge Commit Message:" msgstr "Сообщение слияния:" -#: git-gui.sh:3076 +#: git-gui.sh:3418 msgid "Commit Message:" msgstr "Сообщение коммита:" -#: git-gui.sh:3125 git-gui.sh:3267 lib/console.tcl:73 +#: git-gui.sh:3477 git-gui.sh:3641 lib/console.tcl:73 msgid "Copy All" msgstr "Копировать все" -#: git-gui.sh:3149 lib/blame.tcl:104 +#: git-gui.sh:3501 lib/blame.tcl:106 msgid "File:" msgstr "Файл:" -#: git-gui.sh:3255 +#: git-gui.sh:3549 lib/choose_repository.tcl:1100 +msgid "Open" +msgstr "Открыть" + +#: git-gui.sh:3629 msgid "Refresh" msgstr "Обновить" -#: git-gui.sh:3276 +#: git-gui.sh:3650 msgid "Decrease Font Size" msgstr "Уменьшить размер шрифта" -#: git-gui.sh:3280 +#: git-gui.sh:3654 msgid "Increase Font Size" msgstr "Увеличить размер шрифта" -#: git-gui.sh:3288 lib/blame.tcl:281 +#: git-gui.sh:3662 lib/blame.tcl:296 msgid "Encoding" msgstr "Кодировка" -#: git-gui.sh:3299 +#: git-gui.sh:3673 msgid "Apply/Reverse Hunk" msgstr "Применить/Убрать изменение" -#: git-gui.sh:3304 +#: git-gui.sh:3678 msgid "Apply/Reverse Line" msgstr "Применить/Убрать строку" -#: git-gui.sh:3323 +#: git-gui.sh:3684 git-gui.sh:3794 git-gui.sh:3805 +msgid "Revert Hunk" +msgstr "Обратить изменения блока" + +#: git-gui.sh:3689 git-gui.sh:3801 git-gui.sh:3812 +msgid "Revert Line" +msgstr "Обратить изменения строки" + +#: git-gui.sh:3694 git-gui.sh:3791 +msgid "Undo Last Revert" +msgstr "Отменить последнее обращение изменений" + +#: git-gui.sh:3713 msgid "Run Merge Tool" msgstr "Запустить программу слияния" -#: git-gui.sh:3328 +#: git-gui.sh:3718 msgid "Use Remote Version" msgstr "Взять внешнюю версию" -#: git-gui.sh:3332 +#: git-gui.sh:3722 msgid "Use Local Version" msgstr "Взять локальную версию" -#: git-gui.sh:3336 +#: git-gui.sh:3726 msgid "Revert To Base" msgstr "Обратить изменения" -#: git-gui.sh:3354 +#: git-gui.sh:3744 msgid "Visualize These Changes In The Submodule" msgstr "Показать эти изменения подмодуля" -#: git-gui.sh:3358 +#: git-gui.sh:3748 msgid "Visualize Current Branch History In The Submodule" msgstr "Показать историю текущей ветки подмодуля" -#: git-gui.sh:3362 +#: git-gui.sh:3752 msgid "Visualize All Branch History In The Submodule" msgstr "Показать историю всех веток подмодуля" -#: git-gui.sh:3367 +#: git-gui.sh:3757 msgid "Start git gui In The Submodule" msgstr "Запустить git gui в подмодуле" -#: git-gui.sh:3389 +#: git-gui.sh:3793 msgid "Unstage Hunk From Commit" msgstr "Убрать блок из индекса" -#: git-gui.sh:3391 +#: git-gui.sh:3797 msgid "Unstage Lines From Commit" msgstr "Убрать строки из индекса" -#: git-gui.sh:3393 +#: git-gui.sh:3798 git-gui.sh:3809 +msgid "Revert Lines" +msgstr "Обратить изменения строк" + +#: git-gui.sh:3800 msgid "Unstage Line From Commit" msgstr "Убрать строку из индекса" -#: git-gui.sh:3396 +#: git-gui.sh:3804 msgid "Stage Hunk For Commit" msgstr "Добавить блок в индекс" -#: git-gui.sh:3398 +#: git-gui.sh:3808 msgid "Stage Lines For Commit" msgstr "Добавить строки в индекс" -#: git-gui.sh:3400 +#: git-gui.sh:3811 msgid "Stage Line For Commit" msgstr "Добавить строку в индекс" -#: git-gui.sh:3424 +#: git-gui.sh:3861 msgid "Initializing..." msgstr "Инициализация…" -#: git-gui.sh:3541 +#: git-gui.sh:4017 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -533,14 +579,14 @@ msgid "" "\n" msgstr "Возможны ошибки в переменных окружения.\n\nПеременные окружения, которые возможно\nбудут проигнорированы командами Git,\nзапущенными из %s\n\n" -#: git-gui.sh:3570 +#: git-gui.sh:4046 msgid "" "\n" "This is due to a known issue with the\n" "Tcl binary distributed by Cygwin." msgstr "\nЭто известная проблема с Tcl,\nраспространяемым Cygwin." -#: git-gui.sh:3575 +#: git-gui.sh:4051 #, tcl-format msgid "" "\n" @@ -551,309 +597,148 @@ msgid "" "~/.gitconfig file.\n" msgstr "\n\nВместо использования %s можно\nсохранить значения user.name и\nuser.email в Вашем персональном\nфайле ~/.gitconfig.\n" -#: lib/about.tcl:26 -msgid "git-gui - a graphical user interface for Git." -msgstr "git-gui - графический пользовательский интерфейс к Git." +#: lib/spellcheck.tcl:57 +msgid "Unsupported spell checker" +msgstr "Неподдерживаемая программа проверки правописания" -#: lib/blame.tcl:72 -msgid "File Viewer" -msgstr "Просмотр файла" +#: lib/spellcheck.tcl:65 +msgid "Spell checking is unavailable" +msgstr "Проверка правописания не доступна" -#: lib/blame.tcl:78 -msgid "Commit:" -msgstr "Коммит:" +#: lib/spellcheck.tcl:68 +msgid "Invalid spell checking configuration" +msgstr "Неправильная конфигурация программы проверки правописания" -#: lib/blame.tcl:271 -msgid "Copy Commit" -msgstr "Копировать SHA-1" - -#: lib/blame.tcl:275 -msgid "Find Text..." -msgstr "Найти текст…" - -#: lib/blame.tcl:284 -msgid "Do Full Copy Detection" -msgstr "Провести полный поиск копий" - -#: lib/blame.tcl:288 -msgid "Show History Context" -msgstr "Показать исторический контекст" - -#: lib/blame.tcl:291 -msgid "Blame Parent Commit" -msgstr "Авторы родительского коммита" - -#: lib/blame.tcl:450 +#: lib/spellcheck.tcl:70 #, tcl-format -msgid "Reading %s..." -msgstr "Чтение %s…" +msgid "Reverting dictionary to %s." +msgstr "Словарь вернут к %s." -#: lib/blame.tcl:557 -msgid "Loading copy/move tracking annotations..." -msgstr "Загрузка аннотации копирований/переименований…" +#: lib/spellcheck.tcl:73 +msgid "Spell checker silently failed on startup" +msgstr "Программа проверки правописания не смогла запуститься" -#: lib/blame.tcl:577 -msgid "lines annotated" -msgstr "строк прокомментировано" +#: lib/spellcheck.tcl:80 +msgid "Unrecognized spell checker" +msgstr "Нераспознанная программа проверки правописания" -#: lib/blame.tcl:769 -msgid "Loading original location annotations..." -msgstr "Загрузка аннотаций первоначального положения объекта…" +#: lib/spellcheck.tcl:186 +msgid "No Suggestions" +msgstr "Исправлений не найдено" -#: lib/blame.tcl:772 -msgid "Annotation complete." -msgstr "Аннотация завершена." +#: lib/spellcheck.tcl:388 +msgid "Unexpected EOF from spell checker" +msgstr "Программа проверки правописания прервала передачу данных" -#: lib/blame.tcl:802 -msgid "Busy" -msgstr "Занят" +#: lib/spellcheck.tcl:392 +msgid "Spell Checker Failed" +msgstr "Ошибка проверки правописания" -#: lib/blame.tcl:803 -msgid "Annotation process is already running." -msgstr "Аннотация уже запущена" +#: lib/transport.tcl:6 lib/remote_add.tcl:132 +#, tcl-format +msgid "fetch %s" +msgstr "извлечение %s" -#: lib/blame.tcl:842 -msgid "Running thorough copy detection..." -msgstr "Выполнение полного поиска копий…" +#: lib/transport.tcl:7 +#, tcl-format +msgid "Fetching new changes from %s" +msgstr "Извлечение изменений из %s " -#: lib/blame.tcl:910 -msgid "Loading annotation..." -msgstr "Загрузка аннотации…" +#: lib/transport.tcl:18 +#, tcl-format +msgid "remote prune %s" +msgstr "чистка внешнего %s" -#: lib/blame.tcl:963 -msgid "Author:" -msgstr "Автор:" +#: lib/transport.tcl:19 +#, tcl-format +msgid "Pruning tracking branches deleted from %s" +msgstr "Чистка отслеживаемых веток, удалённых из %s" -#: lib/blame.tcl:967 -msgid "Committer:" -msgstr "Коммитер:" +#: lib/transport.tcl:25 +msgid "fetch all remotes" +msgstr "извлечь со всех внешних репозиториев" -#: lib/blame.tcl:972 -msgid "Original File:" -msgstr "Исходный файл:" +#: lib/transport.tcl:26 +msgid "Fetching new changes from all remotes" +msgstr "Получение изменений со всех внешних репозиториев" -#: lib/blame.tcl:1020 -msgid "Cannot find HEAD commit:" -msgstr "Не удалось найти текущее состояние:" +#: lib/transport.tcl:40 +msgid "remote prune all remotes" +msgstr "чистка всех внешних репозиториев" -#: lib/blame.tcl:1075 -msgid "Cannot find parent commit:" -msgstr "Не удалось найти родительское состояние:" +#: lib/transport.tcl:41 +msgid "Pruning tracking branches deleted from all remotes" +msgstr "Чистка отслеживаемых веток, удалённых со всех внешних репозиториев" -#: lib/blame.tcl:1090 -msgid "Unable to display parent" -msgstr "Не могу показать предка" +#: lib/transport.tcl:54 lib/transport.tcl:92 lib/transport.tcl:110 +#: lib/remote_add.tcl:162 +#, tcl-format +msgid "push %s" +msgstr "отправить %s" -#: lib/blame.tcl:1091 lib/diff.tcl:320 -msgid "Error loading diff:" -msgstr "Ошибка загрузки изменений:" +#: lib/transport.tcl:55 +#, tcl-format +msgid "Pushing changes to %s" +msgstr "Отправка изменений в %s " -#: lib/blame.tcl:1231 -msgid "Originally By:" -msgstr "Источник:" +#: lib/transport.tcl:93 +#, tcl-format +msgid "Mirroring to %s" +msgstr "Точное копирование в %s" -#: lib/blame.tcl:1237 -msgid "In File:" -msgstr "Файл:" +#: lib/transport.tcl:111 +#, tcl-format +msgid "Pushing %s %s to %s" +msgstr "Отправка %s %s в %s" -#: lib/blame.tcl:1242 -msgid "Copied Or Moved Here By:" -msgstr "Скопировано/перемещено в:" +#: lib/transport.tcl:132 +msgid "Push Branches" +msgstr "Отправить ветки" -#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19 -msgid "Checkout Branch" -msgstr "Перейти на ветку" - -#: lib/branch_checkout.tcl:23 -msgid "Checkout" -msgstr "Перейти" - -#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35 -#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:282 -#: lib/checkout_op.tcl:579 lib/choose_font.tcl:43 lib/merge.tcl:172 -#: lib/option.tcl:125 lib/remote_add.tcl:32 lib/remote_branch_delete.tcl:42 -#: lib/tools_dlg.tcl:40 lib/tools_dlg.tcl:204 lib/tools_dlg.tcl:352 -#: lib/transport.tcl:108 +#: lib/transport.tcl:141 lib/checkout_op.tcl:580 lib/remote_add.tcl:34 +#: lib/browser.tcl:292 lib/branch_checkout.tcl:30 lib/branch_rename.tcl:32 +#: lib/choose_font.tcl:45 lib/option.tcl:127 lib/tools_dlg.tcl:41 +#: lib/tools_dlg.tcl:202 lib/tools_dlg.tcl:345 lib/remote_branch_delete.tcl:43 +#: lib/branch_create.tcl:37 lib/branch_delete.tcl:34 lib/merge.tcl:178 msgid "Cancel" msgstr "Отмена" -#: lib/branch_checkout.tcl:32 lib/browser.tcl:287 lib/tools_dlg.tcl:328 -msgid "Revision" -msgstr "Версия" +#: lib/transport.tcl:147 +msgid "Source Branches" +msgstr "Исходные ветки" -#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:280 -msgid "Options" -msgstr "Настройки" +#: lib/transport.tcl:162 +msgid "Destination Repository" +msgstr "Репозиторий назначения" -#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92 -msgid "Fetch Tracking Branch" -msgstr "Извлечь изменения из внешней ветки" +#: lib/transport.tcl:165 lib/remote_branch_delete.tcl:51 +msgid "Remote:" +msgstr "внешний:" -#: lib/branch_checkout.tcl:44 -msgid "Detach From Local Branch" -msgstr "Отсоединить от локальной ветки" +#: lib/transport.tcl:187 lib/remote_branch_delete.tcl:72 +msgid "Arbitrary Location:" +msgstr "Указанное положение:" -#: lib/branch_create.tcl:22 -msgid "Create Branch" -msgstr "Создать ветку" +#: lib/transport.tcl:205 +msgid "Transfer Options" +msgstr "Настройки отправки" -#: lib/branch_create.tcl:27 -msgid "Create New Branch" -msgstr "Создать новую ветку" +#: lib/transport.tcl:207 +msgid "Force overwrite existing branch (may discard changes)" +msgstr "Принудительно перезаписать существующую ветку (возможна потеря изменений)" -#: lib/branch_create.tcl:31 lib/choose_repository.tcl:381 -msgid "Create" -msgstr "Создать" +#: lib/transport.tcl:211 +msgid "Use thin pack (for slow network connections)" +msgstr "Использовать thin pack (для медленных сетевых подключений)" -#: lib/branch_create.tcl:40 -msgid "Branch Name" -msgstr "Имя ветки" +#: lib/transport.tcl:215 +msgid "Include tags" +msgstr "Передать метки" -#: lib/branch_create.tcl:43 lib/remote_add.tcl:39 lib/tools_dlg.tcl:50 -msgid "Name:" -msgstr "Название:" - -#: lib/branch_create.tcl:58 -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 "Только Fast Forward" - -#: lib/branch_create.tcl:85 lib/checkout_op.tcl:571 -msgid "Reset" -msgstr "Сброс" - -#: lib/branch_create.tcl:97 -msgid "Checkout After Creation" -msgstr "После создания сделать текущей" - -#: lib/branch_create.tcl:131 -msgid "Please select a tracking branch." -msgstr "Укажите отлеживаемую ветку." - -#: lib/branch_create.tcl:140 +#: lib/transport.tcl:229 #, tcl-format -msgid "Tracking branch %s is not a branch in the remote repository." -msgstr "Отслеживаемая ветка %s не является веткой на внешнем репозитории." - -#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86 -msgid "Please supply a branch name." -msgstr "Укажите имя ветки." - -#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106 -#, tcl-format -msgid "'%s' is not an acceptable branch name." -msgstr "Недопустимое имя ветки «%s»." - -#: lib/branch_delete.tcl:15 -msgid "Delete Branch" -msgstr "Удаление ветки" - -#: lib/branch_delete.tcl:20 -msgid "Delete Local Branch" -msgstr "Удалить локальную ветку" - -#: lib/branch_delete.tcl:37 -msgid "Local Branches" -msgstr "Локальные ветки" - -#: lib/branch_delete.tcl:52 -msgid "Delete Only If Merged Into" -msgstr "Удалить только в случае, если было слияние с" - -#: lib/branch_delete.tcl:54 lib/remote_branch_delete.tcl:119 -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:217 -msgid "" -"Recovering deleted branches is difficult.\n" -"\n" -"Delete the selected branches?" -msgstr "Восстановить удаленные ветки сложно.\n\nПродолжить?" - -#: lib/branch_delete.tcl:141 -#, tcl-format -msgid "" -"Failed to delete branches:\n" -"%s" -msgstr "Не удалось удалить ветки:\n%s" - -#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22 -msgid "Rename Branch" -msgstr "Переименование ветки" - -#: lib/branch_rename.tcl:26 -msgid "Rename" -msgstr "Переименовать" - -#: lib/branch_rename.tcl:36 -msgid "Branch:" -msgstr "Ветка:" - -#: lib/branch_rename.tcl:39 -msgid "New Name:" -msgstr "Новое название:" - -#: lib/branch_rename.tcl:75 -msgid "Please select a branch to rename." -msgstr "Укажите ветку для переименования." - -#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:202 -#, tcl-format -msgid "Branch '%s' already exists." -msgstr "Ветка «%s» уже существует." - -#: lib/branch_rename.tcl:117 -#, tcl-format -msgid "Failed to rename '%s'." -msgstr "Не удалось переименовать «%s». " - -#: lib/browser.tcl:17 -msgid "Starting..." -msgstr "Запуск…" - -#: lib/browser.tcl:26 -msgid "File Browser" -msgstr "Просмотр списка файлов" - -#: lib/browser.tcl:126 lib/browser.tcl:143 -#, tcl-format -msgid "Loading %s..." -msgstr "Загрузка %s…" - -#: lib/browser.tcl:187 -msgid "[Up To Parent]" -msgstr "[На уровень выше]" - -#: lib/browser.tcl:267 lib/browser.tcl:273 -msgid "Browse Branch Files" -msgstr "Показать файлы ветки" - -#: lib/browser.tcl:278 lib/choose_repository.tcl:398 -#: lib/choose_repository.tcl:486 lib/choose_repository.tcl:497 -#: lib/choose_repository.tcl:1028 -msgid "Browse" -msgstr "Показать" +msgid "%s (%s): Push" +msgstr "%s (%s): Отправка" #: lib/checkout_op.tcl:85 #, tcl-format @@ -865,8 +750,8 @@ msgstr "Извлечение %s из %s " msgid "fatal: Cannot resolve %s" msgstr "критическая ошибка: невозможно разрешить %s" -#: lib/checkout_op.tcl:146 lib/console.tcl:81 lib/database.tcl:31 -#: lib/sshkey.tcl:53 +#: lib/checkout_op.tcl:146 lib/sshkey.tcl:58 lib/console.tcl:81 +#: lib/database.tcl:30 msgid "Close" msgstr "Закрыть" @@ -880,6 +765,11 @@ msgstr "Ветка «%s» не существует." msgid "Failed to configure simplified git-pull for '%s'." msgstr "Ошибка создания упрощённой конфигурации git pull для «%s»." +#: lib/checkout_op.tcl:202 lib/branch_rename.tcl:102 +#, tcl-format +msgid "Branch '%s' already exists." +msgstr "Ветка «%s» уже существует." + #: lib/checkout_op.tcl:229 #, tcl-format msgid "" @@ -921,51 +811,55 @@ msgstr "Обновление рабочего каталога из «%s»…" msgid "files checked out" msgstr "файлы извлечены" -#: lib/checkout_op.tcl:376 +#: lib/checkout_op.tcl:377 #, tcl-format msgid "Aborted checkout of '%s' (file level merging is required)." msgstr "Прерван переход на «%s» (требуется слияние содержимого файлов)" -#: lib/checkout_op.tcl:377 +#: lib/checkout_op.tcl:378 msgid "File level merge required." msgstr "Требуется слияние содержания файлов." -#: lib/checkout_op.tcl:381 +#: lib/checkout_op.tcl:382 #, tcl-format msgid "Staying on branch '%s'." msgstr "Ветка «%s» остаётся текущей." -#: lib/checkout_op.tcl:452 +#: lib/checkout_op.tcl:453 msgid "" "You are no longer on a local branch.\n" "\n" "If you wanted to be on a branch, create one now starting from 'This Detached Checkout'." msgstr "Вы более не находитесь на локальной ветке.\n\nЕсли вы хотите снова вернуться к какой-нибудь ветке, создайте её сейчас, начиная с «Текущего отсоединенного состояния»." -#: lib/checkout_op.tcl:503 lib/checkout_op.tcl:507 +#: lib/checkout_op.tcl:504 lib/checkout_op.tcl:508 #, tcl-format msgid "Checked out '%s'." msgstr "Выполнен переход на «%s»." -#: lib/checkout_op.tcl:535 +#: lib/checkout_op.tcl:536 #, tcl-format msgid "Resetting '%s' to '%s' will lose the following commits:" msgstr "Сброс «%s» на «%s» приведет к потере следующих коммитов:" -#: lib/checkout_op.tcl:557 +#: lib/checkout_op.tcl:558 msgid "Recovering lost commits may not be easy." msgstr "Восстановить потерянные коммиты будет сложно." -#: lib/checkout_op.tcl:562 +#: lib/checkout_op.tcl:563 #, tcl-format msgid "Reset '%s'?" msgstr "Сбросить «%s»?" -#: lib/checkout_op.tcl:567 lib/merge.tcl:164 lib/tools_dlg.tcl:343 +#: lib/checkout_op.tcl:568 lib/tools_dlg.tcl:336 lib/merge.tcl:170 msgid "Visualize" msgstr "Наглядно" -#: lib/checkout_op.tcl:635 +#: lib/checkout_op.tcl:572 lib/branch_create.tcl:85 +msgid "Reset" +msgstr "Сброс" + +#: lib/checkout_op.tcl:636 #, tcl-format msgid "" "Failed to set current branch.\n" @@ -975,576 +869,498 @@ msgid "" "This should not have occurred. %s will now close and give up." msgstr "Не удалось установить текущую ветку.\n\nВаш рабочий каталог обновлён только частично. Были обновлены все файлы кроме служебных файлов Git. \n\nЭтого не должно было произойти. %s завершается." -#: lib/choose_font.tcl:39 +#: 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:41 lib/tools_dlg.tcl:51 lib/branch_create.tcl:44 +msgid "Name:" +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: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:163 +#, tcl-format +msgid "Setting up the %s (at %s)" +msgstr "Настройка %s (в %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:437 +#: lib/choose_repository.tcl:524 lib/choose_repository.tcl:533 +#: lib/choose_repository.tcl:1115 +msgid "Browse" +msgstr "Показать" + +#: lib/browser.tcl:297 lib/branch_checkout.tcl:35 lib/tools_dlg.tcl:321 +msgid "Revision" +msgstr "Версия" + +#: 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." +msgstr "Не удалось обновить индекс Git. Состояние репозитория будет перечитано автоматически." + +#: lib/index.tcl:43 +msgid "Continue" +msgstr "Продолжить" + +#: lib/index.tcl:46 +msgid "Unlock Index" +msgstr "Разблокировать индекс" + +#: lib/index.tcl:77 lib/index.tcl:146 lib/index.tcl:220 lib/index.tcl:587 +#: lib/choose_repository.tcl:999 +msgid "files" +msgstr "файлов" + +#: lib/index.tcl:326 +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:563 +msgid "Do Nothing" +msgstr "Ничего не делать" + +#: lib/index.tcl:545 +#, tcl-format +msgid "Delete untracked file %s?" +msgstr "Удалить неотслеживаемый файл %s?" + +#: lib/index.tcl:550 +#, tcl-format +msgid "Delete these %i untracked files?" +msgstr "Удалить %i неотслеживаемые файла?" + +#: lib/index.tcl:560 +msgid "Files will be permanently deleted." +msgstr "Файлы будут удалены навсегда." + +#: lib/index.tcl:564 +msgid "Delete Files" +msgstr "Удалить файлы" + +#: lib/index.tcl:586 +msgid "Deleting" +msgstr "Удаление" + +#: lib/index.tcl:665 +msgid "Encountered errors deleting files:\n" +msgstr "Возникшие ошибки при удалении файлов:\n" + +#: lib/index.tcl:674 +#, tcl-format +msgid "None of the %d selected files could be deleted." +msgstr "Не удалось удалить ни один из выбранных %d файлов." + +#: lib/index.tcl:679 +#, tcl-format +msgid "%d of the %d selected files could not be deleted." +msgstr "Не удалось удалить %d из выбранных %d файлов." + +#: lib/index.tcl:726 +msgid "Reverting selected files" +msgstr "Обращение изменений в выбранных файлах" + +#: lib/index.tcl:730 +#, tcl-format +msgid "Reverting %s" +msgstr "Обращение изменений в %s" + +#: 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:39 lib/option.tcl:310 lib/branch_create.tcl:69 +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/status_bar.tcl:263 +#, tcl-format +msgid "%s ... %*i of %*i %s (%3i%%)" +msgstr "%s … %*i из %*i %s (%3i%%)" + +#: 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/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:92 lib/branch_create.tcl:154 +msgid "Please supply a branch name." +msgstr "Укажите имя ветки." + +#: lib/branch_rename.tcl:112 lib/branch_create.tcl:165 +#, tcl-format +msgid "'%s' is not an acceptable branch name." +msgstr "Недопустимое имя ветки «%s»." + +#: lib/branch_rename.tcl:123 +#, tcl-format +msgid "Failed to rename '%s'." +msgstr "Не удалось переименовать «%s». " + +#: lib/choose_font.tcl:41 msgid "Select" msgstr "Выбрать" -#: lib/choose_font.tcl:53 +#: lib/choose_font.tcl:55 msgid "Font Family" msgstr "Шрифт" -#: lib/choose_font.tcl:74 +#: lib/choose_font.tcl:76 msgid "Font Size" msgstr "Размер шрифта" -#: lib/choose_font.tcl:91 +#: lib/choose_font.tcl:93 msgid "Font Example" msgstr "Пример текста" -#: lib/choose_font.tcl:103 +#: lib/choose_font.tcl:105 msgid "" "This is example text.\n" "If you like this text, it can be your font." msgstr "Это пример текста.\nЕсли Вам нравится этот текст, это может быть Ваш шрифт." -#: lib/choose_repository.tcl:28 -msgid "Git Gui" -msgstr "Git Gui" - -#: lib/choose_repository.tcl:87 lib/choose_repository.tcl:386 -msgid "Create New Repository" -msgstr "Создать новый репозиторий" - -#: lib/choose_repository.tcl:93 -msgid "New..." -msgstr "Новый…" - -#: lib/choose_repository.tcl:100 lib/choose_repository.tcl:471 -msgid "Clone Existing Repository" -msgstr "Склонировать существующий репозиторий" - -#: lib/choose_repository.tcl:106 -msgid "Clone..." -msgstr "Клонировать…" - -#: lib/choose_repository.tcl:113 lib/choose_repository.tcl:1016 -msgid "Open Existing Repository" -msgstr "Выбрать существующий репозиторий" - -#: lib/choose_repository.tcl:119 -msgid "Open..." -msgstr "Открыть…" - -#: lib/choose_repository.tcl:132 -msgid "Recent Repositories" -msgstr "Недавние репозитории" - -#: lib/choose_repository.tcl:138 -msgid "Open Recent Repository:" -msgstr "Открыть последний репозиторий" - -#: lib/choose_repository.tcl:306 lib/choose_repository.tcl:313 -#: lib/choose_repository.tcl:320 +#: lib/option.tcl:11 #, tcl-format -msgid "Failed to create repository %s:" -msgstr "Не удалось создать репозиторий %s:" +msgid "Invalid global encoding '%s'" +msgstr "Неверная глобальная кодировка «%s»" -#: lib/choose_repository.tcl:391 -msgid "Directory:" -msgstr "Каталог:" - -#: lib/choose_repository.tcl:423 lib/choose_repository.tcl:550 -#: lib/choose_repository.tcl:1052 -msgid "Git Repository" -msgstr "Репозиторий" - -#: lib/choose_repository.tcl:448 +#: lib/option.tcl:19 #, tcl-format -msgid "Directory %s already exists." -msgstr "Каталог '%s' уже существует." +msgid "Invalid repo encoding '%s'" +msgstr "Неверная кодировка репозитория «%s»" -#: lib/choose_repository.tcl:452 +#: lib/option.tcl:119 +msgid "Restore Defaults" +msgstr "Восстановить настройки по умолчанию" + +#: lib/option.tcl:123 +msgid "Save" +msgstr "Сохранить" + +#: lib/option.tcl:133 #, tcl-format -msgid "File %s already exists." -msgstr "Файл '%s' уже существует." +msgid "%s Repository" +msgstr "Для репозитория %s" -#: lib/choose_repository.tcl:466 -msgid "Clone" -msgstr "Склонировать" +#: lib/option.tcl:134 +msgid "Global (All Repositories)" +msgstr "Общие (для всех репозиториев)" -#: lib/choose_repository.tcl:479 -msgid "Source Location:" -msgstr "Исходное положение:" +#: lib/option.tcl:140 +msgid "User Name" +msgstr "Имя пользователя" -#: lib/choose_repository.tcl:490 -msgid "Target Directory:" -msgstr "Каталог назначения:" +#: lib/option.tcl:141 +msgid "Email Address" +msgstr "Адрес электронной почты" -#: lib/choose_repository.tcl:502 -msgid "Clone Type:" -msgstr "Тип клона:" +#: lib/option.tcl:143 +msgid "Summarize Merge Commits" +msgstr "Суммарное сообщение при слиянии" -#: lib/choose_repository.tcl:508 -msgid "Standard (Fast, Semi-Redundant, Hardlinks)" -msgstr "Стандартный (Быстрый, полуизбыточный, «жесткие» ссылки)" +#: lib/option.tcl:144 +msgid "Merge Verbosity" +msgstr "Уровень детальности сообщений при слиянии" -#: lib/choose_repository.tcl:514 -msgid "Full Copy (Slower, Redundant Backup)" -msgstr "Полная копия (Медленный, создает резервную копию)" +#: lib/option.tcl:145 +msgid "Show Diffstat After Merge" +msgstr "Показать отчет об изменениях после слияния" -#: lib/choose_repository.tcl:520 -msgid "Shared (Fastest, Not Recommended, No Backup)" -msgstr "Общий (Самый быстрый, не рекомендуется, без резервной копии)" +#: lib/option.tcl:146 +msgid "Use Merge Tool" +msgstr "Использовать для слияния программу" -#: lib/choose_repository.tcl:556 lib/choose_repository.tcl:603 -#: lib/choose_repository.tcl:749 lib/choose_repository.tcl:819 -#: lib/choose_repository.tcl:1058 lib/choose_repository.tcl:1066 +#: 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 "Число строк в контексте diff" + +#: lib/option.tcl:157 +msgid "Additional Diff Parameters" +msgstr "Дополнительные параметры для diff" + +#: 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 "Предупреждать перед коммитом в отделённый HEAD" + +#: 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:182 lib/option.tcl:197 lib/option.tcl:220 lib/option.tcl:282 +#: lib/database.tcl:57 #, tcl-format -msgid "Not a Git repository: %s" -msgstr "Каталог не является репозиторием: %s" +msgid "%s:" +msgstr "%s:" -#: lib/choose_repository.tcl:592 -msgid "Standard only available for local repository." -msgstr "Стандартный клон возможен только для локального репозитория." +#: lib/option.tcl:210 +msgid "Change" +msgstr "Изменить" -#: lib/choose_repository.tcl:596 -msgid "Shared only available for local repository." -msgstr "Общий клон возможен только для локального репозитория." +#: lib/option.tcl:254 +msgid "Spelling Dictionary:" +msgstr "Словарь для проверки правописания:" -#: lib/choose_repository.tcl:617 +#: lib/option.tcl:284 +msgid "Change Font" +msgstr "Изменить" + +#: lib/option.tcl:288 #, tcl-format -msgid "Location %s already exists." -msgstr "Путь '%s' уже существует." +msgid "Choose %s" +msgstr "Выберите %s" -#: lib/choose_repository.tcl:628 -msgid "Failed to configure origin" -msgstr "Не могу сконфигурировать исходный репозиторий." +#: lib/option.tcl:294 +msgid "pt." +msgstr "п." -#: lib/choose_repository.tcl:640 -msgid "Counting objects" -msgstr "Считаю объекты" +#: lib/option.tcl:308 +msgid "Preferences" +msgstr "Настройки" -#: lib/choose_repository.tcl:641 -msgid "buckets" -msgstr "блоки" - -#: lib/choose_repository.tcl:665 -#, tcl-format -msgid "Unable to copy objects/info/alternates: %s" -msgstr "Не могу скопировать objects/info/alternates: %s" - -#: lib/choose_repository.tcl:701 -#, tcl-format -msgid "Nothing to clone from %s." -msgstr "Нечего клонировать с %s." - -#: lib/choose_repository.tcl:703 lib/choose_repository.tcl:917 -#: lib/choose_repository.tcl:929 -msgid "The 'master' branch has not been initialized." -msgstr "Не инициализирована ветвь «master»." - -#: lib/choose_repository.tcl:716 -msgid "Hardlinks are unavailable. Falling back to copying." -msgstr "«Жесткие ссылки» недоступны. Будет использовано копирование." - -#: lib/choose_repository.tcl:728 -#, tcl-format -msgid "Cloning from %s" -msgstr "Клонирование %s" - -#: lib/choose_repository.tcl:759 -msgid "Copying objects" -msgstr "Копирование objects" - -#: lib/choose_repository.tcl:760 -msgid "KiB" -msgstr "КБ" - -#: lib/choose_repository.tcl:784 -#, tcl-format -msgid "Unable to copy object: %s" -msgstr "Не могу скопировать объект: %s" - -#: lib/choose_repository.tcl:794 -msgid "Linking objects" -msgstr "Создание ссылок на objects" - -#: lib/choose_repository.tcl:795 -msgid "objects" -msgstr "объекты" - -#: lib/choose_repository.tcl:803 -#, tcl-format -msgid "Unable to hardlink object: %s" -msgstr "Не могу создать «жесткую ссылку» на объект: %s" - -#: lib/choose_repository.tcl:858 -msgid "Cannot fetch branches and objects. See console output for details." -msgstr "Не удалось извлечь ветки и объекты. Дополнительная информация на консоли." - -#: lib/choose_repository.tcl:869 -msgid "Cannot fetch tags. See console output for details." -msgstr "Не удалось извлечь метки. Дополнительная информация на консоли." - -#: lib/choose_repository.tcl:893 -msgid "Cannot determine HEAD. See console output for details." -msgstr "Не могу определить HEAD. Дополнительная информация на консоли." - -#: lib/choose_repository.tcl:902 -#, tcl-format -msgid "Unable to cleanup %s" -msgstr "Не могу очистить %s" - -#: lib/choose_repository.tcl:908 -msgid "Clone failed." -msgstr "Клонирование не удалось." - -#: lib/choose_repository.tcl:915 -msgid "No default branch obtained." -msgstr "Ветка по умолчанию не была получена." - -#: lib/choose_repository.tcl:926 -#, tcl-format -msgid "Cannot resolve %s as a commit." -msgstr "Не могу распознать %s как коммит." - -#: lib/choose_repository.tcl:938 -msgid "Creating working directory" -msgstr "Создаю рабочий каталог" - -#: lib/choose_repository.tcl:939 lib/index.tcl:67 lib/index.tcl:130 -#: lib/index.tcl:198 -msgid "files" -msgstr "файлов" - -#: lib/choose_repository.tcl:968 -msgid "Initial file checkout failed." -msgstr "Не удалось получить начальное состояние файлов репозитория." - -#: lib/choose_repository.tcl:1011 -msgid "Open" -msgstr "Открыть" - -#: lib/choose_repository.tcl:1021 -msgid "Repository:" -msgstr "Репозиторий:" - -#: lib/choose_repository.tcl:1072 -#, tcl-format -msgid "Failed to open repository %s:" -msgstr "Не удалось открыть репозиторий %s:" - -#: lib/choose_rev.tcl:53 -msgid "This Detached Checkout" -msgstr "Текущее отсоединенное состояние" - -#: lib/choose_rev.tcl:60 -msgid "Revision Expression:" -msgstr "Выражение для определения версии:" - -#: lib/choose_rev.tcl:74 -msgid "Local Branch" -msgstr "Локальная ветка:" - -#: lib/choose_rev.tcl:79 -msgid "Tracking Branch" -msgstr "Отслеживаемая ветка" - -#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:538 -msgid "Tag" -msgstr "Метка" - -#: lib/choose_rev.tcl:317 -#, tcl-format -msgid "Invalid revision: %s" -msgstr "Неверная версия: %s" - -#: lib/choose_rev.tcl:338 -msgid "No revision selected." -msgstr "Версия не указана." - -#: lib/choose_rev.tcl:346 -msgid "Revision expression is empty." -msgstr "Пустое выражение для определения версии." - -#: lib/choose_rev.tcl:531 -msgid "Updated" -msgstr "Обновлено" - -#: lib/choose_rev.tcl:559 -msgid "URL" -msgstr "Ссылка" - -#: lib/commit.tcl:9 -msgid "" -"There is nothing to amend.\n" -"\n" -"You are about to create the initial commit. There is no commit before this to amend.\n" -msgstr "Отсутствует коммиты для исправления.\n\nВы создаете начальный коммит, здесь еще нечего исправлять.\n" - -#: lib/commit.tcl:18 -msgid "" -"Cannot amend while merging.\n" -"\n" -"You are currently in the middle of a merge that has not been fully completed. You cannot amend the prior commit unless you first abort the current merge activity.\n" -msgstr "Невозможно исправить коммит во время слияния.\n\nТекущее слияние не завершено. Невозможно исправить предыдуий коммит, не прерывая эту операцию.\n" - -#: lib/commit.tcl:48 -msgid "Error loading commit data for amend:" -msgstr "Ошибка при загрузке данных для исправления коммита:" - -#: lib/commit.tcl:75 -msgid "Unable to obtain your identity:" -msgstr "Невозможно получить информацию об авторстве:" - -#: lib/commit.tcl:80 -msgid "Invalid GIT_COMMITTER_IDENT:" -msgstr "Недопустимый GIT_COMMITTER_IDENT:" - -#: lib/commit.tcl:129 -#, tcl-format -msgid "warning: Tcl does not support encoding '%s'." -msgstr "предупреждение: Tcl не поддерживает кодировку «%s»." - -#: lib/commit.tcl:149 -msgid "" -"Last scanned state does not match repository state.\n" -"\n" -"Another Git program has modified this repository since the last scan. A rescan must be performed before another commit can be created.\n" -"\n" -"The rescan will be automatically started now.\n" -msgstr "Последнее прочитанное состояние репозитория не соответствует текущему.\n\nС момента последней проверки репозиторий был изменен другой программой Git. Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь. \n\nЭто будет сделано сейчас автоматически.\n" - -#: lib/commit.tcl:172 -#, tcl-format -msgid "" -"Unmerged files cannot be committed.\n" -"\n" -"File %s has merge conflicts. You must resolve them and stage the file before committing.\n" -msgstr "Нельзя выполнить коммит с незавершённой операцией слияния.\n\nДля файла %s возник конфликт слияния. Разрешите конфликт и добавьте их в индекс перед выполнением коммита.\n" - -#: lib/commit.tcl:180 -#, tcl-format -msgid "" -"Unknown file state %s detected.\n" -"\n" -"File %s cannot be committed by this program.\n" -msgstr "Обнаружено неизвестное состояние файла %s.\n\nФайл %s не может быть закоммичен этой программой.\n" - -#: lib/commit.tcl:188 -msgid "" -"No changes to commit.\n" -"\n" -"You must stage at least 1 file before you can commit.\n" -msgstr "Отсутствуют изменения для сохранения.\n\nДобавьте в индекс хотя бы один файл перед выполнением коммита.\n" - -#: lib/commit.tcl:203 -msgid "" -"Please supply a commit message.\n" -"\n" -"A good commit message has the following format:\n" -"\n" -"- First line: Describe in one sentence what you did.\n" -"- Second line: Blank\n" -"- Remaining lines: Describe why this change is good.\n" -msgstr "Укажите сообщение коммита.\n\nРекомендуется следующий формат сообщения:\n\n- в первой строке краткое описание сделанных изменений\n- вторая строка пустая\n- в оставшихся строках опишите, что дают ваши изменения\n" - -#: lib/commit.tcl:234 -msgid "Calling pre-commit hook..." -msgstr "Вызов перехватчика pre-commit…" - -#: lib/commit.tcl:249 -msgid "Commit declined by pre-commit hook." -msgstr "Коммит прерван переватчиком pre-commit." - -#: lib/commit.tcl:272 -msgid "Calling commit-msg hook..." -msgstr "Вызов перехватчика commit-msg…" - -#: lib/commit.tcl:287 -msgid "Commit declined by commit-msg hook." -msgstr "Коммит прерван переватчиком commit-msg" - -#: lib/commit.tcl:300 -msgid "Committing changes..." -msgstr "Коммит изменений…" - -#: lib/commit.tcl:316 -msgid "write-tree failed:" -msgstr "Программа write-tree завершилась с ошибкой:" - -#: lib/commit.tcl:317 lib/commit.tcl:361 lib/commit.tcl:382 -msgid "Commit failed." -msgstr "Не удалось закоммитить изменения." - -#: lib/commit.tcl:334 -#, tcl-format -msgid "Commit %s appears to be corrupt" -msgstr "Коммит %s похоже поврежден" - -#: lib/commit.tcl:339 -msgid "" -"No changes to commit.\n" -"\n" -"No files were modified by this commit and it was not a merge commit.\n" -"\n" -"A rescan will be automatically started now.\n" -msgstr "Нет изменения для коммита.\n\nНи один файл не был изменен и не было слияния.\n\nСейчас автоматически запустится перечитывание репозитория.\n" - -#: lib/commit.tcl:346 -msgid "No changes to commit." -msgstr "Нет изменения для коммита." - -#: lib/commit.tcl:360 -msgid "commit-tree failed:" -msgstr "Программа commit-tree завершилась с ошибкой:" - -#: lib/commit.tcl:381 -msgid "update-ref failed:" -msgstr "Программа update-ref завершилась с ошибкой:" - -#: lib/commit.tcl:469 -#, 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:43 -msgid "Number of loose objects" -msgstr "Количество несвязанных объектов" - -#: lib/database.tcl:44 -msgid "Disk space used by loose objects" -msgstr "Объем дискового пространства, занятый несвязанными объектами" - -#: lib/database.tcl:45 -msgid "Number of packed objects" -msgstr "Количество упакованных объектов" - -#: lib/database.tcl:46 -msgid "Number of packs" -msgstr "Количество pack-файлов" - -#: lib/database.tcl:47 -msgid "Disk space used by packed objects" -msgstr "Объем дискового пространства, занятый упакованными объектами" - -#: lib/database.tcl:48 -msgid "Packed objects waiting for pruning" -msgstr "Несвязанные объекты, которые можно удалить" - -#: lib/database.tcl:49 -msgid "Garbage files" -msgstr "Мусор" - -#: lib/database.tcl:72 -msgid "Compressing the object database" -msgstr "Сжатие базы объектов" - -#: lib/database.tcl:83 -msgid "Verifying the object database with fsck-objects" -msgstr "Проверка базы объектов при помощи fsck" - -#: lib/database.tcl:107 -#, tcl-format -msgid "" -"This repository currently has approximately %i loose objects.\n" -"\n" -"To maintain optimal performance it is strongly recommended that you compress the database.\n" -"\n" -"Compress the database now?" -msgstr "Этот репозиторий сейчас содержит примерно %i свободных объектов\n\nДля лучшей производительности рекомендуется сжать базу данных.\n\nСжать базу данных сейчас?" - -#: lib/date.tcl:25 -#, tcl-format -msgid "Invalid date from Git: %s" -msgstr "Неправильная дата в репозитории: %s" - -#: lib/diff.tcl:64 -#, tcl-format -msgid "" -"No differences detected.\n" -"\n" -"%s has no changes.\n" -"\n" -"The modification date of this file was updated by another application, but the content within the file was not changed.\n" -"\n" -"A rescan will be automatically started to find other files which may have the same state." -msgstr "Изменений не обнаружено.\n\nв %s отсутствуют изменения.\n\nДата изменения файла была обновлена другой программой, но содержимое файла осталось прежним.\n\nСейчас будет запущено перечитывание репозитория, чтобы найти подобные файлы." - -#: lib/diff.tcl:104 -#, tcl-format -msgid "Loading diff of %s..." -msgstr "Загрузка изменений %s…" - -#: lib/diff.tcl:125 -msgid "" -"LOCAL: deleted\n" -"REMOTE:\n" -msgstr "ЛОКАЛЬНО: удалён\nВНЕШНИЙ:\n" - -#: lib/diff.tcl:130 -msgid "" -"REMOTE: deleted\n" -"LOCAL:\n" -msgstr "ВНЕШНИЙ: удалён\nЛОКАЛЬНО:\n" - -#: lib/diff.tcl:137 -msgid "LOCAL:\n" -msgstr "ЛОКАЛЬНО:\n" - -#: lib/diff.tcl:140 -msgid "REMOTE:\n" -msgstr "ВНЕШНИЙ:\n" - -#: lib/diff.tcl:202 lib/diff.tcl:319 -#, tcl-format -msgid "Unable to display %s" -msgstr "Не могу показать %s" - -#: lib/diff.tcl:203 -msgid "Error loading file:" -msgstr "Ошибка загрузки файла:" - -#: lib/diff.tcl:210 -msgid "Git Repository (subproject)" -msgstr "Репозиторий Git (подпроект)" - -#: lib/diff.tcl:222 -msgid "* Binary file (not showing content)." -msgstr "* Двоичный файл (содержимое не показано)" - -#: lib/diff.tcl:227 -#, tcl-format -msgid "" -"* Untracked file is %d bytes.\n" -"* Showing only first %d bytes.\n" -msgstr "* Размер неотслеживаемого файла %d байт.\n* Показано первых %d байт.\n" - -#: lib/diff.tcl:233 -#, tcl-format -msgid "" -"\n" -"* Untracked file clipped here by %s.\n" -"* To see the entire file, use an external editor.\n" -msgstr "\n* Неотслеживаемый файл обрезан: %s.\n* Чтобы увидеть весь файл, используйте внешний редактор.\n" - -#: lib/diff.tcl:482 -msgid "Failed to unstage selected hunk." -msgstr "Не удалось исключить выбранную часть." - -#: lib/diff.tcl:489 -msgid "Failed to stage selected hunk." -msgstr "Не удалось проиндексировать выбранный блок изменений." - -#: lib/diff.tcl:568 -msgid "Failed to unstage selected line." -msgstr "Не удалось исключить выбранную строку." - -#: lib/diff.tcl:576 -msgid "Failed to stage selected line." -msgstr "Не удалось проиндексировать выбранную строку." +#: lib/option.tcl:345 +msgid "Failed to completely save options:" +msgstr "Не удалось полностью сохранить настройки:" #: lib/encoding.tcl:443 msgid "Default" @@ -1559,184 +1375,40 @@ msgstr "Системная (%s)" msgid "Other" msgstr "Другая" -#: lib/error.tcl:20 lib/error.tcl:114 -msgid "error" -msgstr "ошибка" - -#: lib/error.tcl:36 -msgid "warning" -msgstr "предупреждение" - -#: lib/error.tcl:94 -msgid "You must correct the above errors before committing." -msgstr "Перед коммитом, исправьте вышеуказанные ошибки." - -#: lib/index.tcl:6 -msgid "Unable to unlock the index." -msgstr "Не удалось разблокировать индекс" - -#: lib/index.tcl:15 -msgid "Index Error" -msgstr "Ошибка в индексе" - -#: lib/index.tcl:17 -msgid "" -"Updating the Git index failed. A rescan will be automatically started to " -"resynchronize git-gui." -msgstr "Не удалось обновить индекс Git. Состояние репозитория будет перечитано автоматически." - -#: lib/index.tcl:28 -msgid "Continue" -msgstr "Продолжить" - -#: lib/index.tcl:31 -msgid "Unlock Index" -msgstr "Разблокировать индекс" - -#: lib/index.tcl:289 +#: lib/tools.tcl:76 #, tcl-format -msgid "Unstaging %s from commit" -msgstr "Удаление %s из индекса" +msgid "Running %s requires a selected file." +msgstr "Запуск %s требует выбранного файла." -#: lib/index.tcl:328 -msgid "Ready to commit." -msgstr "Готов для коммита." - -#: lib/index.tcl:341 +#: lib/tools.tcl:92 #, tcl-format -msgid "Adding %s" -msgstr "Добавление %s…" +msgid "Are you sure you want to run %1$s on file \"%2$s\"?" +msgstr "Вы действительно хотите выполнить %1$s на «%2$s»?" -#: lib/index.tcl:398 +#: lib/tools.tcl:96 #, tcl-format -msgid "Revert changes in file %s?" -msgstr "Обратить изменения в файле %s?" +msgid "Are you sure you want to run %s?" +msgstr "Действительно запустить %s?" -#: lib/index.tcl:400 +#: lib/tools.tcl:118 #, tcl-format -msgid "Revert changes in these %i files?" -msgstr "Обратить изменения в %i файле(-ах)?" +msgid "Tool: %s" +msgstr "Вспомогательная операция: %s" -#: lib/index.tcl:408 -msgid "Any unstaged changes will be permanently lost by the revert." -msgstr "Любые непроиндексированные изменения, будут потеряны при обращении изменений." - -#: lib/index.tcl:411 -msgid "Do Nothing" -msgstr "Ничего не делать" - -#: lib/index.tcl:429 -msgid "Reverting selected files" -msgstr "Обращение изменений в выбранных файлах" - -#: lib/index.tcl:433 +#: lib/tools.tcl:119 #, tcl-format -msgid "Reverting %s" -msgstr "Обращение изменений в %s" +msgid "Running: %s" +msgstr "Выполнение: %s" -#: lib/merge.tcl:13 -msgid "" -"Cannot merge while amending.\n" -"\n" -"You must finish amending this commit before starting any type of merge.\n" -msgstr "Невозможно выполнить слияние во время исправления.\n\nЗавершите исправление данного коммита перед выполнением операции слияния.\n" - -#: lib/merge.tcl:27 -msgid "" -"Last scanned state does not match repository state.\n" -"\n" -"Another Git program has modified this repository since the last scan. A rescan must be performed before a merge can be performed.\n" -"\n" -"The rescan will be automatically started now.\n" -msgstr "Последнее прочитанное состояние репозитория не соответствует текущему.\n\nС момента последней проверки репозиторий был изменен другой программой Git. Необходимо перечитать репозиторий, прежде чем слияние может быть сделано.\n\nЭто будет сделано сейчас автоматически.\n" - -#: lib/merge.tcl:45 +#: lib/tools.tcl:158 #, tcl-format -msgid "" -"You are in the middle of a conflicted merge.\n" -"\n" -"File %s has merge conflicts.\n" -"\n" -"You must resolve them, stage the file, and commit to complete the current merge. Only then can you begin another merge.\n" -msgstr "Предыдущее слияние не завершено из-за конфликта.\n\nДля файла %s возник конфликт слияния.\n\nРазрешите конфликт, добавьте файл в индекс и закоммитьте. Только после этого можно начать следующее слияние.\n" +msgid "Tool completed successfully: %s" +msgstr "Программа %s завершилась успешно." -#: lib/merge.tcl:55 +#: lib/tools.tcl:160 #, tcl-format -msgid "" -"You are in the middle of a change.\n" -"\n" -"File %s is modified.\n" -"\n" -"You should complete the current commit before starting a merge. Doing so will help you abort a failed merge, should the need arise.\n" -msgstr "Вы находитесь в процессе изменений.\n\nФайл %s изменён.\n\nВы должны завершить текущий коммит перед началом слияния. В случае необходимости, это позволит прервать операцию слияния.\n" - -#: lib/merge.tcl:107 -#, tcl-format -msgid "%s of %s" -msgstr "%s из %s" - -#: lib/merge.tcl:120 -#, tcl-format -msgid "Merging %s and %s..." -msgstr "Слияние %s и %s…" - -#: lib/merge.tcl:131 -msgid "Merge completed successfully." -msgstr "Слияние успешно завершено." - -#: lib/merge.tcl:133 -msgid "Merge failed. Conflict resolution is required." -msgstr "Не удалось завершить слияние. Требуется разрешение конфликта." - -#: lib/merge.tcl:158 -#, tcl-format -msgid "Merge Into %s" -msgstr "Слияние с %s" - -#: lib/merge.tcl:177 -msgid "Revision To Merge" -msgstr "Версия, с которой провести слияние" - -#: lib/merge.tcl:212 -msgid "" -"Cannot abort while amending.\n" -"\n" -"You must finish amending this commit.\n" -msgstr "Невозможно прервать исправление.\n\nЗавершите текущее исправление коммита.\n" - -#: lib/merge.tcl:222 -msgid "" -"Abort merge?\n" -"\n" -"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n" -"\n" -"Continue with aborting the current merge?" -msgstr "Прервать операцию слияния?\n\nПрерывание текущего слияния приведет к потере *ВСЕХ* несохраненных изменений.\n\nПродолжить?" - -#: lib/merge.tcl:228 -msgid "" -"Reset changes?\n" -"\n" -"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n" -"\n" -"Continue with resetting the current changes?" -msgstr "Сбросить изменения?\n\nСброс изменений приведет к потере *ВСЕХ* несохраненных изменений.\n\nПродолжить?" - -#: lib/merge.tcl:239 -msgid "Aborting" -msgstr "Прерываю" - -#: lib/merge.tcl:239 -msgid "files reset" -msgstr "изменения в файлах отменены" - -#: lib/merge.tcl:267 -msgid "Abort failed." -msgstr "Прервать не удалось." - -#: lib/merge.tcl:269 -msgid "Abort completed. Ready." -msgstr "Прервано." +msgid "Tool failed: %s" +msgstr "Ошибка выполнения программы: %s" #: lib/mergetool.tcl:8 msgid "Force resolution to the base version?" @@ -1778,28 +1450,28 @@ msgstr "Программа слияния не обрабатывает конф msgid "Conflict file does not exist" msgstr "Конфликтующий файл не существует" -#: lib/mergetool.tcl:264 +#: lib/mergetool.tcl:246 #, tcl-format msgid "Not a GUI merge tool: '%s'" msgstr "«%s» не является программой слияния" -#: lib/mergetool.tcl:268 +#: lib/mergetool.tcl:275 #, tcl-format msgid "Unsupported merge tool '%s'" msgstr "Неподдерживаемая программа слияния «%s»" -#: lib/mergetool.tcl:303 +#: lib/mergetool.tcl:310 msgid "Merge tool is already running, terminate it?" msgstr "Программа слияния уже работает. Прервать?" -#: lib/mergetool.tcl:323 +#: lib/mergetool.tcl:330 #, tcl-format msgid "" "Error retrieving versions:\n" "%s" msgstr "Ошибка получения версий:\n%s" -#: lib/mergetool.tcl:343 +#: lib/mergetool.tcl:350 #, tcl-format msgid "" "Could not start the merge tool:\n" @@ -1807,259 +1479,177 @@ msgid "" "%s" msgstr "Ошибка запуска программы слияния:\n\n%s" -#: lib/mergetool.tcl:347 +#: lib/mergetool.tcl:354 msgid "Running merge tool..." msgstr "Запуск программы слияния…" -#: lib/mergetool.tcl:375 lib/mergetool.tcl:383 +#: lib/mergetool.tcl:382 lib/mergetool.tcl:390 msgid "Merge tool failed." msgstr "Ошибка выполнения программы слияния." -#: lib/option.tcl:11 +#: lib/tools_dlg.tcl:22 #, tcl-format -msgid "Invalid global encoding '%s'" -msgstr "Неверная глобальная кодировка «%s»" +msgid "%s (%s): Add Tool" +msgstr "%s (%s): Добавить инструмент" -#: lib/option.tcl:19 +#: 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 "Invalid repo encoding '%s'" -msgstr "Неверная кодировка репозитория «%s»" +msgid "Tool '%s' already exists." +msgstr "Вспомогательная операция «%s» уже существует." -#: lib/option.tcl:117 -msgid "Restore Defaults" -msgstr "Восстановить настройки по умолчанию" - -#: lib/option.tcl:121 -msgid "Save" -msgstr "Сохранить" - -#: lib/option.tcl:131 +#: lib/tools_dlg.tcl:148 #, tcl-format -msgid "%s Repository" -msgstr "Для репозитория %s" +msgid "" +"Could not add tool:\n" +"%s" +msgstr "Ошибка добавления программы:\n%s" -#: lib/option.tcl:132 -msgid "Global (All Repositories)" -msgstr "Общие (для всех репозиториев)" - -#: lib/option.tcl:138 -msgid "User Name" -msgstr "Имя пользователя" - -#: lib/option.tcl:139 -msgid "Email Address" -msgstr "Адрес электронной почты" - -#: lib/option.tcl:141 -msgid "Summarize Merge Commits" -msgstr "Суммарное сообщение при слиянии" - -#: lib/option.tcl:142 -msgid "Merge Verbosity" -msgstr "Уровень детальности сообщений при слиянии" - -#: lib/option.tcl:143 -msgid "Show Diffstat After Merge" -msgstr "Показать отчет об изменениях после слияния" - -#: lib/option.tcl:144 -msgid "Use Merge Tool" -msgstr "Использовать для слияния программу" - -#: lib/option.tcl:146 -msgid "Trust File Modification Timestamps" -msgstr "Доверять времени модификации файла" - -#: lib/option.tcl:147 -msgid "Prune Tracking Branches During Fetch" -msgstr "Чистка отслеживаемых веток при извлечении изменений" - -#: lib/option.tcl:148 -msgid "Match Tracking Branches" -msgstr "Такое же имя, как и у отслеживаемой ветки" - -#: lib/option.tcl:149 -msgid "Blame Copy Only On Changed Files" -msgstr "Поиск копий только в изменённых файлах" - -#: lib/option.tcl:150 -msgid "Minimum Letters To Blame Copy On" -msgstr "Минимальное количество символов для поиска копий" - -#: lib/option.tcl:151 -msgid "Blame History Context Radius (days)" -msgstr "Радиус исторического контекста (в днях)" - -#: lib/option.tcl:152 -msgid "Number of Diff Context Lines" -msgstr "Число строк в контексте diff" - -#: lib/option.tcl:153 -msgid "Commit Message Text Width" -msgstr "Ширина текста сообщения коммита" - -#: lib/option.tcl:154 -msgid "New Branch Name Template" -msgstr "Шаблон для имени новой ветки" - -#: lib/option.tcl:155 -msgid "Default File Contents Encoding" -msgstr "Кодировка содержания файла по умолчанию" - -#: lib/option.tcl:203 -msgid "Change" -msgstr "Изменить" - -#: lib/option.tcl:230 -msgid "Spelling Dictionary:" -msgstr "Словарь для проверки правописания:" - -#: lib/option.tcl:254 -msgid "Change Font" -msgstr "Изменить" - -#: lib/option.tcl:258 +#: lib/tools_dlg.tcl:187 #, tcl-format -msgid "Choose %s" -msgstr "Выберите %s" +msgid "%s (%s): Remove Tool" +msgstr "%s (%s): Удалить инструмент" -#: lib/option.tcl:264 -msgid "pt." -msgstr "pt." +#: lib/tools_dlg.tcl:193 +msgid "Remove Tool Commands" +msgstr "Удалить команды программы" -#: lib/option.tcl:278 -msgid "Preferences" -msgstr "Настройки" +#: lib/tools_dlg.tcl:198 +msgid "Remove" +msgstr "Удалить" -#: lib/option.tcl:314 -msgid "Failed to completely save options:" -msgstr "Не удалось полностью сохранить настройки:" +#: lib/tools_dlg.tcl:231 +msgid "(Blue denotes repository-local tools)" +msgstr "(Синим выделены программы локальные репозиторию)" -#: lib/remote.tcl:163 -msgid "Remove Remote" -msgstr "Удалить ссылку на внешний репозиторий" - -#: lib/remote.tcl:168 -msgid "Prune from" -msgstr "Чистка" - -#: lib/remote.tcl:173 -msgid "Fetch from" -msgstr "Извлечение из" - -#: lib/remote.tcl:215 -msgid "Push to" -msgstr "Отправить" - -#: lib/remote_add.tcl:19 -msgid "Add Remote" -msgstr "Зарегистрировать внешний репозиторий" - -#: lib/remote_add.tcl:24 -msgid "Add New Remote" -msgstr "Добавить внешний репозиторий" - -#: lib/remote_add.tcl:28 lib/tools_dlg.tcl:36 -msgid "Add" -msgstr "Добавить" - -#: lib/remote_add.tcl:37 -msgid "Remote Details" -msgstr "Информация о внешнем репозитории" - -#: lib/remote_add.tcl:50 -msgid "Location:" -msgstr "Положение:" - -#: lib/remote_add.tcl:62 -msgid "Further Action" -msgstr "Следующая операция" - -#: lib/remote_add.tcl:65 -msgid "Fetch Immediately" -msgstr "Сразу извлечь изменения" - -#: lib/remote_add.tcl:71 -msgid "Initialize Remote Repository and Push" -msgstr "Инициализировать внешний репозиторий и отправить" - -#: lib/remote_add.tcl:77 -msgid "Do Nothing Else Now" -msgstr "Больше ничего не делать" - -#: lib/remote_add.tcl:101 -msgid "Please supply a remote name." -msgstr "Укажите название внешнего репозитория." - -#: lib/remote_add.tcl:114 +#: lib/tools_dlg.tcl:283 #, tcl-format -msgid "'%s' is not an acceptable remote name." -msgstr "«%s» не является допустимым именем внешнего репозитория." +msgid "%s (%s):" +msgstr "%s (%s):" -#: lib/remote_add.tcl:125 +#: lib/tools_dlg.tcl:292 #, tcl-format -msgid "Failed to add remote '%s' of location '%s'." -msgstr "Не удалось добавить «%s» из «%s». " +msgid "Run Command: %s" +msgstr "Запуск команды: %s" -#: lib/remote_add.tcl:133 lib/transport.tcl:6 +#: lib/tools_dlg.tcl:306 +msgid "Arguments" +msgstr "Аргументы" + +#: lib/tools_dlg.tcl:341 +msgid "OK" +msgstr "OK" + +#: 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:43 lib/shortcut.tcl:75 #, tcl-format -msgid "fetch %s" -msgstr "извлечение %s" +msgid "%s (%s): Create Desktop Icon" +msgstr "%s (%s): Создать ярлык на рабочем столе" -#: lib/remote_add.tcl:134 +#: lib/shortcut.tcl:24 lib/shortcut.tcl:65 +msgid "Cannot write shortcut:" +msgstr "Невозможно записать ссылку:" + +#: lib/shortcut.tcl:140 +msgid "Cannot write icon:" +msgstr "Невозможно записать значок:" + +#: lib/remote_branch_delete.tcl:29 #, tcl-format -msgid "Fetching the %s" -msgstr "Извлечение %s" +msgid "%s (%s): Delete Branch Remotely" +msgstr "%s (%s): Удаление внешней ветки" -#: lib/remote_add.tcl:157 -#, tcl-format -msgid "Do not know how to initialize repository at location '%s'." -msgstr "Невозможно инициализировать репозиторий в «%s»." - -#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:63 -#: lib/transport.tcl:81 -#, tcl-format -msgid "push %s" -msgstr "отправить %s" - -#: lib/remote_add.tcl:164 -#, tcl-format -msgid "Setting up the %s (at %s)" -msgstr "Настройка %s (в %s)" - -#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34 +#: lib/remote_branch_delete.tcl:34 msgid "Delete Branch Remotely" msgstr "Удаление ветки во внешнем репозитории" -#: lib/remote_branch_delete.tcl:47 +#: lib/remote_branch_delete.tcl:48 msgid "From Repository" msgstr "Из репозитория" -#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:134 -msgid "Remote:" -msgstr "внешний:" - -#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:149 -msgid "Arbitrary Location:" -msgstr "Указанное положение:" - -#: lib/remote_branch_delete.tcl:84 +#: lib/remote_branch_delete.tcl:88 msgid "Branches" msgstr "Ветки" -#: lib/remote_branch_delete.tcl:109 +#: lib/remote_branch_delete.tcl:110 msgid "Delete Only If" msgstr "Удалить только в случае, если" -#: lib/remote_branch_delete.tcl:111 +#: lib/remote_branch_delete.tcl:112 msgid "Merged Into:" msgstr "Слияние с:" -#: lib/remote_branch_delete.tcl:152 +#: lib/remote_branch_delete.tcl:120 lib/branch_delete.tcl:53 +msgid "Always (Do not perform merge checks)" +msgstr "Всегда (не выполнять проверку на слияние)" + +#: lib/remote_branch_delete.tcl:153 msgid "A branch is required for 'Merged Into'." msgstr "Для операции «Слияние с» требуется указать ветку." -#: lib/remote_branch_delete.tcl:184 +#: lib/remote_branch_delete.tcl:185 #, tcl-format msgid "" "The following branches are not completely merged into %s:\n" @@ -2067,118 +1657,509 @@ msgid "" " - %s" msgstr "Следующие ветки могут быть объединены с %s при помощи операции слияния:\n\n - %s" -#: lib/remote_branch_delete.tcl:189 +#: lib/remote_branch_delete.tcl:190 #, tcl-format msgid "" "One or more of the merge tests failed because you have not fetched the " "necessary commits. Try fetching from %s first." msgstr "Некоторые тесты на слияние не прошли, потому что вы не извлекли необходимые коммиты. Попытайтесь извлечь их из %s." -#: lib/remote_branch_delete.tcl:207 +#: lib/remote_branch_delete.tcl:208 msgid "Please select one or more branches to delete." msgstr "Укажите одну или несколько веток для удаления." -#: lib/remote_branch_delete.tcl:226 +#: lib/remote_branch_delete.tcl:218 lib/branch_delete.tcl:115 +msgid "" +"Recovering deleted branches is difficult.\n" +"\n" +"Delete the selected branches?" +msgstr "Восстановить удаленные ветки сложно.\n\nПродолжить?" + +#: lib/remote_branch_delete.tcl:227 #, tcl-format msgid "Deleting branches from %s" msgstr "Удаление веток из %s" -#: lib/remote_branch_delete.tcl:292 +#: lib/remote_branch_delete.tcl:300 msgid "No repository selected." msgstr "Не указан репозиторий." -#: lib/remote_branch_delete.tcl:297 +#: lib/remote_branch_delete.tcl:305 #, tcl-format msgid "Scanning %s..." msgstr "Перечитывание %s…" -#: lib/search.tcl:21 -msgid "Find:" -msgstr "Поиск:" +#: lib/choose_repository.tcl:45 +msgid "Git Gui" +msgstr "Git Gui" -#: lib/search.tcl:23 -msgid "Next" -msgstr "Дальше" +#: lib/choose_repository.tcl:104 lib/choose_repository.tcl:427 +msgid "Create New Repository" +msgstr "Создать новый репозиторий" -#: lib/search.tcl:24 -msgid "Prev" -msgstr "Обратно" +#: lib/choose_repository.tcl:110 +msgid "New..." +msgstr "Новый…" -#: lib/search.tcl:25 -msgid "Case-Sensitive" -msgstr "Игн. большие/маленькие" +#: lib/choose_repository.tcl:117 lib/choose_repository.tcl:511 +msgid "Clone Existing Repository" +msgstr "Склонировать существующий репозиторий" -#: lib/shortcut.tcl:21 lib/shortcut.tcl:62 -msgid "Cannot write shortcut:" -msgstr "Невозможно записать ссылку:" +#: lib/choose_repository.tcl:128 +msgid "Clone..." +msgstr "Клонировать…" -#: lib/shortcut.tcl:137 -msgid "Cannot write icon:" -msgstr "Невозможно записать значок:" +#: lib/choose_repository.tcl:135 lib/choose_repository.tcl:1105 +msgid "Open Existing Repository" +msgstr "Выбрать существующий репозиторий" -#: lib/spellcheck.tcl:57 -msgid "Unsupported spell checker" -msgstr "Неподдерживаемая программа проверки правописания" +#: lib/choose_repository.tcl:141 +msgid "Open..." +msgstr "Открыть…" -#: lib/spellcheck.tcl:65 -msgid "Spell checking is unavailable" -msgstr "Проверка правописания не доступна" +#: lib/choose_repository.tcl:154 +msgid "Recent Repositories" +msgstr "Недавние репозитории" -#: lib/spellcheck.tcl:68 -msgid "Invalid spell checking configuration" -msgstr "Неправильная конфигурация программы проверки правописания" +#: lib/choose_repository.tcl:164 +msgid "Open Recent Repository:" +msgstr "Открыть последний репозиторий" -#: lib/spellcheck.tcl:70 +#: lib/choose_repository.tcl:331 lib/choose_repository.tcl:338 +#: lib/choose_repository.tcl:345 #, tcl-format -msgid "Reverting dictionary to %s." -msgstr "Словарь вернут к %s." +msgid "Failed to create repository %s:" +msgstr "Не удалось создать репозиторий %s:" -#: lib/spellcheck.tcl:73 -msgid "Spell checker silently failed on startup" -msgstr "Программа проверки правописания не смогла запуститься" +#: lib/choose_repository.tcl:422 lib/branch_create.tcl:33 +msgid "Create" +msgstr "Создать" -#: lib/spellcheck.tcl:80 -msgid "Unrecognized spell checker" -msgstr "Нераспознанная программа проверки правописания" +#: lib/choose_repository.tcl:432 +msgid "Directory:" +msgstr "Каталог:" -#: lib/spellcheck.tcl:186 -msgid "No Suggestions" -msgstr "Исправлений не найдено" +#: lib/choose_repository.tcl:462 lib/choose_repository.tcl:588 +#: lib/choose_repository.tcl:1139 +msgid "Git Repository" +msgstr "Репозиторий" -#: lib/spellcheck.tcl:388 -msgid "Unexpected EOF from spell checker" -msgstr "Программа проверки правописания прервала передачу данных" +#: lib/choose_repository.tcl:487 +#, tcl-format +msgid "Directory %s already exists." +msgstr "Каталог '%s' уже существует." -#: lib/spellcheck.tcl:392 -msgid "Spell Checker Failed" -msgstr "Ошибка проверки правописания" +#: lib/choose_repository.tcl:491 +#, tcl-format +msgid "File %s already exists." +msgstr "Файл '%s' уже существует." -#: lib/sshkey.tcl:31 +#: lib/choose_repository.tcl:506 +msgid "Clone" +msgstr "Склонировать" + +#: lib/choose_repository.tcl:519 +msgid "Source Location:" +msgstr "Исходное положение:" + +#: lib/choose_repository.tcl:528 +msgid "Target Directory:" +msgstr "Каталог назначения:" + +#: lib/choose_repository.tcl:538 +msgid "Clone Type:" +msgstr "Тип клона:" + +#: lib/choose_repository.tcl:543 +msgid "Standard (Fast, Semi-Redundant, Hardlinks)" +msgstr "Стандартный (Быстрый, полуизбыточный, «жесткие» ссылки)" + +#: lib/choose_repository.tcl:548 +msgid "Full Copy (Slower, Redundant Backup)" +msgstr "Полная копия (Медленный, создает резервную копию)" + +#: lib/choose_repository.tcl:553 +msgid "Shared (Fastest, Not Recommended, No Backup)" +msgstr "Общий (Самый быстрый, не рекомендуется, без резервной копии)" + +#: lib/choose_repository.tcl:560 +msgid "Recursively clone submodules too" +msgstr "Также рекурсивно клонировать подмодули" + +#: lib/choose_repository.tcl:594 lib/choose_repository.tcl:641 +#: lib/choose_repository.tcl:790 lib/choose_repository.tcl:864 +#: lib/choose_repository.tcl:1145 lib/choose_repository.tcl:1153 +#, tcl-format +msgid "Not a Git repository: %s" +msgstr "Каталог не является репозиторием Git: %s" + +#: lib/choose_repository.tcl:630 +msgid "Standard only available for local repository." +msgstr "Стандартный клон возможен только для локального репозитория." + +#: lib/choose_repository.tcl:634 +msgid "Shared only available for local repository." +msgstr "Общий клон возможен только для локального репозитория." + +#: lib/choose_repository.tcl:655 +#, tcl-format +msgid "Location %s already exists." +msgstr "Путь %s уже существует." + +#: lib/choose_repository.tcl:666 +msgid "Failed to configure origin" +msgstr "Не удалось сконфигурировать исходный репозиторий" + +#: lib/choose_repository.tcl:678 +msgid "Counting objects" +msgstr "Подсчёт объектов" + +#: lib/choose_repository.tcl:679 +msgid "buckets" +msgstr "блоки" + +#: lib/choose_repository.tcl:703 +#, tcl-format +msgid "Unable to copy objects/info/alternates: %s" +msgstr "Не удалось скопировать objects/info/alternates: %s" + +#: lib/choose_repository.tcl:740 +#, tcl-format +msgid "Nothing to clone from %s." +msgstr "Нечего клонировать с %s." + +#: lib/choose_repository.tcl:742 lib/choose_repository.tcl:962 +#: lib/choose_repository.tcl:974 +msgid "The 'master' branch has not been initialized." +msgstr "Не инициализирована ветка «master»." + +#: lib/choose_repository.tcl:755 +msgid "Hardlinks are unavailable. Falling back to copying." +msgstr "Жесткие ссылки недоступны. Будет использовано копирование." + +#: lib/choose_repository.tcl:769 +#, tcl-format +msgid "Cloning from %s" +msgstr "Клонирование из %s" + +#: lib/choose_repository.tcl:800 +msgid "Copying objects" +msgstr "Копирование объектов" + +#: lib/choose_repository.tcl:801 +msgid "KiB" +msgstr "КБ" + +#: lib/choose_repository.tcl:825 +#, tcl-format +msgid "Unable to copy object: %s" +msgstr "Не могу скопировать объект: %s" + +#: lib/choose_repository.tcl:837 +msgid "Linking objects" +msgstr "Создание ссылок на objects" + +#: lib/choose_repository.tcl:838 +msgid "objects" +msgstr "объекты" + +#: lib/choose_repository.tcl:846 +#, tcl-format +msgid "Unable to hardlink object: %s" +msgstr "Не могу создать «жесткую ссылку» на объект: %s" + +#: lib/choose_repository.tcl:903 +msgid "Cannot fetch branches and objects. See console output for details." +msgstr "Не удалось извлечь ветки и объекты. Дополнительная информация на консоли." + +#: lib/choose_repository.tcl:914 +msgid "Cannot fetch tags. See console output for details." +msgstr "Не удалось извлечь метки. Дополнительная информация на консоли." + +#: lib/choose_repository.tcl:938 +msgid "Cannot determine HEAD. See console output for details." +msgstr "Не могу определить HEAD. Дополнительная информация на консоли." + +#: lib/choose_repository.tcl:947 +#, tcl-format +msgid "Unable to cleanup %s" +msgstr "Не могу очистить %s" + +#: lib/choose_repository.tcl:953 +msgid "Clone failed." +msgstr "Клонирование не удалось." + +#: lib/choose_repository.tcl:960 +msgid "No default branch obtained." +msgstr "Ветка по умолчанию не была получена." + +#: lib/choose_repository.tcl:971 +#, tcl-format +msgid "Cannot resolve %s as a commit." +msgstr "Не могу распознать %s как коммит." + +#: lib/choose_repository.tcl:998 +msgid "Creating working directory" +msgstr "Создаю рабочий каталог" + +#: lib/choose_repository.tcl:1028 +msgid "Initial file checkout failed." +msgstr "Не удалось получить начальное состояние файлов репозитория." + +#: lib/choose_repository.tcl:1072 +msgid "Cloning submodules" +msgstr "Клонирование подмодулей" + +#: lib/choose_repository.tcl:1087 +msgid "Cannot clone submodules." +msgstr "Не удалось клонировать подмодули." + +#: lib/choose_repository.tcl:1110 +msgid "Repository:" +msgstr "Репозиторий:" + +#: lib/choose_repository.tcl:1159 +#, tcl-format +msgid "Failed to open repository %s:" +msgstr "Не удалось открыть репозиторий %s:" + +#: 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 "Копировать SHA-1" + +#: 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:468 +#, tcl-format +msgid "Reading %s..." +msgstr "Чтение %s…" + +#: lib/blame.tcl:596 +msgid "Loading copy/move tracking annotations..." +msgstr "Загрузка аннотации копирований/переименований…" + +#: lib/blame.tcl:613 +msgid "lines annotated" +msgstr "строк прокомментировано" + +#: lib/blame.tcl:815 +msgid "Loading original location annotations..." +msgstr "Загрузка аннотаций первоначального положения объекта…" + +#: lib/blame.tcl:818 +msgid "Annotation complete." +msgstr "Аннотация завершена." + +#: lib/blame.tcl:849 +msgid "Busy" +msgstr "Занят" + +#: lib/blame.tcl:850 +msgid "Annotation process is already running." +msgstr "Аннотация уже запущена" + +#: lib/blame.tcl:889 +msgid "Running thorough copy detection..." +msgstr "Выполнение полного поиска копий…" + +#: lib/blame.tcl:957 +msgid "Loading annotation..." +msgstr "Загрузка аннотации…" + +#: lib/blame.tcl:1010 +msgid "Author:" +msgstr "Автор:" + +#: lib/blame.tcl:1014 +msgid "Committer:" +msgstr "Коммитер:" + +#: lib/blame.tcl:1019 +msgid "Original File:" +msgstr "Исходный файл:" + +#: lib/blame.tcl:1067 +msgid "Cannot find HEAD commit:" +msgstr "Не удалось найти текущее состояние:" + +#: lib/blame.tcl:1122 +msgid "Cannot find parent commit:" +msgstr "Не удалось найти родительское состояние:" + +#: lib/blame.tcl:1137 +msgid "Unable to display parent" +msgstr "Не могу показать предка" + +#: lib/blame.tcl:1138 lib/diff.tcl:345 +msgid "Error loading diff:" +msgstr "Ошибка загрузки изменений:" + +#: lib/blame.tcl:1279 +msgid "Originally By:" +msgstr "Источник:" + +#: lib/blame.tcl:1285 +msgid "In File:" +msgstr "Файл:" + +#: lib/blame.tcl:1290 +msgid "Copied Or Moved Here By:" +msgstr "Скопировано/перемещено в:" + +#: lib/diff.tcl:77 +#, tcl-format +msgid "" +"No differences detected.\n" +"\n" +"%s has no changes.\n" +"\n" +"The modification date of this file was updated by another application, but the content within the file was not changed.\n" +"\n" +"A rescan will be automatically started to find other files which may have the same state." +msgstr "Изменений не обнаружено.\n\nв %s отсутствуют изменения.\n\nДата изменения файла была обновлена другой программой, но содержимое файла осталось прежним.\n\nСейчас будет запущено перечитывание репозитория, чтобы найти подобные файлы." + +#: lib/diff.tcl:117 +#, tcl-format +msgid "Loading diff of %s..." +msgstr "Загрузка изменений %s…" + +#: lib/diff.tcl:143 +msgid "" +"LOCAL: deleted\n" +"REMOTE:\n" +msgstr "ЛОКАЛЬНО: удалён\nВНЕШНИЙ:\n" + +#: lib/diff.tcl:148 +msgid "" +"REMOTE: deleted\n" +"LOCAL:\n" +msgstr "ВНЕШНИЙ: удалён\nЛОКАЛЬНО:\n" + +#: lib/diff.tcl:155 +msgid "LOCAL:\n" +msgstr "ЛОКАЛЬНО:\n" + +#: lib/diff.tcl:158 +msgid "REMOTE:\n" +msgstr "ВНЕШНИЙ:\n" + +#: lib/diff.tcl:220 lib/diff.tcl:344 +#, tcl-format +msgid "Unable to display %s" +msgstr "Не могу показать %s" + +#: lib/diff.tcl:221 +msgid "Error loading file:" +msgstr "Ошибка загрузки файла:" + +#: lib/diff.tcl:227 +msgid "Git Repository (subproject)" +msgstr "Репозиторий Git (подпроект)" + +#: lib/diff.tcl:239 +msgid "* Binary file (not showing content)." +msgstr "* Двоичный файл (содержимое не показано)" + +#: lib/diff.tcl:244 +#, tcl-format +msgid "" +"* Untracked file is %d bytes.\n" +"* Showing only first %d bytes.\n" +msgstr "* Размер неотслеживаемого файла %d байт.\n* Показано первых %d байт.\n" + +#: lib/diff.tcl:250 +#, tcl-format +msgid "" +"\n" +"* Untracked file clipped here by %s.\n" +"* To see the entire file, use an external editor.\n" +msgstr "\n* Неотслеживаемый файл обрезан: %s.\n* Чтобы увидеть весь файл, используйте внешний редактор.\n" + +#: lib/diff.tcl:583 +msgid "Failed to unstage selected hunk." +msgstr "Не удалось исключить выбранную часть." + +#: lib/diff.tcl:591 +msgid "Failed to revert selected hunk." +msgstr "Не удалось обратить изменения выбранного блока." + +#: lib/diff.tcl:594 +msgid "Failed to stage selected hunk." +msgstr "Не удалось проиндексировать выбранный блок изменений." + +#: lib/diff.tcl:687 +msgid "Failed to unstage selected line." +msgstr "Не удалось исключить выбранную строку." + +#: lib/diff.tcl:696 +msgid "Failed to revert selected line." +msgstr "Не удалось обратить изменения выбраной строки." + +#: lib/diff.tcl:700 +msgid "Failed to stage selected line." +msgstr "Не удалось проиндексировать выбранную строку." + +#: lib/diff.tcl:889 +msgid "Failed to undo last revert." +msgstr "Не удалось отменить посленднее обращение изменений." + +#: lib/sshkey.tcl:34 msgid "No keys found." msgstr "Ключ не найден" -#: lib/sshkey.tcl:34 +#: lib/sshkey.tcl:37 #, tcl-format msgid "Found a public key in: %s" msgstr "Публичный ключ из %s" -#: lib/sshkey.tcl:40 +#: lib/sshkey.tcl:43 msgid "Generate Key" msgstr "Создать ключ" -#: lib/sshkey.tcl:56 +#: lib/sshkey.tcl:61 msgid "Copy To Clipboard" msgstr "Скопировать в буфер обмена" -#: lib/sshkey.tcl:70 +#: lib/sshkey.tcl:75 msgid "Your OpenSSH Public Key" msgstr "Ваш публичный ключ OpenSSH" -#: lib/sshkey.tcl:78 +#: lib/sshkey.tcl:83 msgid "Generating..." msgstr "Создание…" -#: lib/sshkey.tcl:84 +#: lib/sshkey.tcl:89 #, tcl-format msgid "" "Could not start ssh-keygen:\n" @@ -2186,197 +2167,485 @@ msgid "" "%s" msgstr "Ошибка запуска ssh-keygen:\n\n%s" -#: lib/sshkey.tcl:111 +#: lib/sshkey.tcl:116 msgid "Generation failed." msgstr "Ключ не создан." -#: lib/sshkey.tcl:118 +#: lib/sshkey.tcl:123 msgid "Generation succeeded, but no keys found." msgstr "Создание ключа завершилось, но результат не был найден" -#: lib/sshkey.tcl:121 +#: lib/sshkey.tcl:126 #, tcl-format msgid "Your key is in: %s" msgstr "Ваш ключ находится в: %s" -#: lib/status_bar.tcl:83 +#: lib/branch_create.tcl:23 #, tcl-format -msgid "%s ... %*i of %*i %s (%3i%%)" -msgstr "%s … %*i из %*i %s (%3i%%)" +msgid "%s (%s): Create Branch" +msgstr "%s (%s): Создание ветки" -#: lib/tools.tcl:75 +#: lib/branch_create.tcl:28 +msgid "Create New Branch" +msgstr "Создать новую ветку" + +#: lib/branch_create.tcl:42 +msgid "Branch 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 "Только Fast Forward" + +#: 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 "Running %s requires a selected file." -msgstr "Запуск %s требует выбранного файла." +msgid "Tracking branch %s is not a branch in the remote repository." +msgstr "Отслеживаемая ветка %s не является веткой на внешнем репозитории." -#: lib/tools.tcl:90 +#: 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/line.tcl:17 +msgid "Goto Line:" +msgstr "Перейти на строку:" + +#: lib/line.tcl:23 +msgid "Go" +msgstr "Перейти" + +#: 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 "Are you sure you want to run %s?" -msgstr "Действительно запустить %s?" +msgid "Invalid revision: %s" +msgstr "Неверная версия: %s" -#: lib/tools.tcl:110 +#: 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" +"You are about to create the initial commit. There is no commit before this to amend.\n" +msgstr "Отсутствует коммиты для исправления.\n\nВы создаете начальный коммит, здесь еще нечего исправлять.\n" + +#: lib/commit.tcl:18 +msgid "" +"Cannot amend while merging.\n" +"\n" +"You are currently in the middle of a merge that has not been fully completed. You cannot amend the prior commit unless you first abort the current merge activity.\n" +msgstr "Невозможно исправить коммит во время слияния.\n\nТекущее слияние не завершено. Невозможно исправить предыдуий коммит, не прерывая эту операцию.\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 "Tool: %s" -msgstr "Вспомогательная операция: %s" +msgid "warning: Tcl does not support encoding '%s'." +msgstr "предупреждение: Tcl не поддерживает кодировку «%s»." -#: lib/tools.tcl:111 -#, tcl-format -msgid "Running: %s" -msgstr "Выполнение: %s" +#: lib/commit.tcl:158 +msgid "" +"Last scanned state does not match repository state.\n" +"\n" +"Another Git program has modified this repository since the last scan. A rescan must be performed before another commit can be created.\n" +"\n" +"The rescan will be automatically started now.\n" +msgstr "Последнее прочитанное состояние репозитория не соответствует текущему.\n\nС момента последней проверки репозиторий был изменен другой программой Git. Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь. \n\nЭто будет сделано сейчас автоматически.\n" -#: lib/tools.tcl:149 -#, tcl-format -msgid "Tool completed successfully: %s" -msgstr "Программа %s завершилась успешно." - -#: lib/tools.tcl:151 -#, tcl-format -msgid "Tool failed: %s" -msgstr "Ошибка выполнения программы: %s" - -#: lib/tools_dlg.tcl:22 -msgid "Add Tool" -msgstr "Добавить вспомогательную операцию" - -#: lib/tools_dlg.tcl:28 -msgid "Add New Tool Command" -msgstr "Новая вспомогательная операция" - -#: lib/tools_dlg.tcl:33 -msgid "Add globally" -msgstr "Добавить для всех репозиториев" - -#: lib/tools_dlg.tcl:45 -msgid "Tool Details" -msgstr "Описание вспомогательной операции" - -#: lib/tools_dlg.tcl:48 -msgid "Use '/' separators to create a submenu tree:" -msgstr "Используйте «/» для создания подменю" - -#: lib/tools_dlg.tcl:61 -msgid "Command:" -msgstr "Команда:" - -#: lib/tools_dlg.tcl:74 -msgid "Show a dialog before running" -msgstr "Показать диалог перед запуском" - -#: lib/tools_dlg.tcl:80 -msgid "Ask the user to select a revision (sets $REVISION)" -msgstr "Запрос на выбор версии (устанавливает $REVISION)" - -#: lib/tools_dlg.tcl:85 -msgid "Ask the user for additional arguments (sets $ARGS)" -msgstr "Запрос дополнительных аргументов (устанавливает $ARGS)" - -#: lib/tools_dlg.tcl:92 -msgid "Don't show the command output window" -msgstr "Не показывать окно вывода команды" - -#: lib/tools_dlg.tcl:97 -msgid "Run only if a diff is selected ($FILENAME not empty)" -msgstr "Запуск только если показан список изменений ($FILENAME не пусто)" - -#: lib/tools_dlg.tcl:121 -msgid "Please supply a name for the tool." -msgstr "Укажите название вспомогательной операции." - -#: lib/tools_dlg.tcl:129 -#, tcl-format -msgid "Tool '%s' already exists." -msgstr "Вспомогательная операция «%s» уже существует." - -#: lib/tools_dlg.tcl:151 +#: lib/commit.tcl:182 #, tcl-format msgid "" -"Could not add tool:\n" +"Unmerged files cannot be committed.\n" +"\n" +"File %s has merge conflicts. You must resolve them and stage the file before committing.\n" +msgstr "Нельзя выполнить коммит с незавершённой операцией слияния.\n\nДля файла %s возник конфликт слияния. Разрешите конфликт и добавьте их в индекс перед выполнением коммита.\n" + +#: lib/commit.tcl:190 +#, tcl-format +msgid "" +"Unknown file state %s detected.\n" +"\n" +"File %s cannot be committed by this program.\n" +msgstr "Обнаружено неизвестное состояние файла %s.\n\nФайл %s не может быть закоммичен этой программой.\n" + +#: lib/commit.tcl:198 +msgid "" +"No changes to commit.\n" +"\n" +"You must stage at least 1 file before you can commit.\n" +msgstr "Отсутствуют изменения для сохранения.\n\nДобавьте в индекс хотя бы один файл перед выполнением коммита.\n" + +#: lib/commit.tcl:213 +msgid "" +"Please supply a commit message.\n" +"\n" +"A good commit message has the following format:\n" +"\n" +"- First line: Describe in one sentence what you did.\n" +"- Second line: Blank\n" +"- Remaining lines: Describe why this change is good.\n" +msgstr "Укажите сообщение коммита.\n\nРекомендуется следующий формат сообщения:\n\n- в первой строке краткое описание сделанных изменений\n- вторая строка пустая\n- в оставшихся строках опишите, что дают ваши изменения\n" + +#: lib/commit.tcl:244 +msgid "Calling pre-commit hook..." +msgstr "Вызов перехватчика pre-commit…" + +#: lib/commit.tcl:259 +msgid "Commit declined by pre-commit hook." +msgstr "Коммит прерван переватчиком pre-commit." + +#: lib/commit.tcl:278 +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 changes and it can be difficult to retrieve them later from the reflog. You should probably cancel this commit and create a new branch to continue.\n" +" \n" +" Do you really want to proceed with your Commit?" +msgstr "Вы собираетесь сделать коммит в отделённый HEAD. Это действие потенциально опасно, так как если вы переключитесь на другую ветку после этого, то вы потеряете свои изменения и их сложно будет потом найти с помощью журнала ссылок (reflog). Вам скорее всего следует отменить этот коммит и создать новую ветку до продолжения.\n \n Вы действительно хотите продолжить и создать коммит?" + +#: lib/commit.tcl:299 +msgid "Calling commit-msg hook..." +msgstr "Вызов перехватчика commit-msg…" + +#: lib/commit.tcl:314 +msgid "Commit declined by commit-msg hook." +msgstr "Коммит прерван переватчиком commit-msg" + +#: lib/commit.tcl:327 +msgid "Committing changes..." +msgstr "Коммит изменений…" + +#: lib/commit.tcl:344 +msgid "write-tree failed:" +msgstr "Программа write-tree завершилась с ошибкой:" + +#: lib/commit.tcl:345 lib/commit.tcl:395 lib/commit.tcl:422 +msgid "Commit failed." +msgstr "Не удалось закоммитить изменения." + +#: lib/commit.tcl:362 +#, tcl-format +msgid "Commit %s appears to be corrupt" +msgstr "Коммит %s похоже поврежден" + +#: lib/commit.tcl:367 +msgid "" +"No changes to commit.\n" +"\n" +"No files were modified by this commit and it was not a merge commit.\n" +"\n" +"A rescan will be automatically started now.\n" +msgstr "Нет изменения для коммита.\n\nНи один файл не был изменен и не было слияния.\n\nСейчас автоматически запустится перечитывание репозитория.\n" + +#: lib/commit.tcl:374 +msgid "No changes to commit." +msgstr "Нет изменения для коммита." + +#: lib/commit.tcl:394 +msgid "commit-tree failed:" +msgstr "Программа commit-tree завершилась с ошибкой:" + +#: lib/commit.tcl:421 +msgid "update-ref failed:" +msgstr "Программа update-ref завершилась с ошибкой:" + +#: lib/commit.tcl:514 +#, tcl-format +msgid "Created commit %s: %s" +msgstr "Создан коммит %s: %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:103 +#, tcl-format +msgid "The following branches are not completely merged into %s:" +msgstr "Ветки, которые не полностью сливаются с %s:" + +#: lib/branch_delete.tcl:131 +#, tcl-format +msgid " - %s:" +msgstr " — %s:" + +#: lib/branch_delete.tcl:141 +#, tcl-format +msgid "" +"Failed to delete branches:\n" "%s" -msgstr "Ошибка добавления программы:\n%s" +msgstr "Не удалось удалить ветки:\n%s" -#: lib/tools_dlg.tcl:190 -msgid "Remove Tool" -msgstr "Удалить программу" - -#: lib/tools_dlg.tcl:196 -msgid "Remove Tool Commands" -msgstr "Удалить команды программы" - -#: lib/tools_dlg.tcl:200 -msgid "Remove" -msgstr "Удалить" - -#: lib/tools_dlg.tcl:236 -msgid "(Blue denotes repository-local tools)" -msgstr "(Синим выделены программы локальные репозиторию)" - -#: lib/tools_dlg.tcl:297 +#: lib/date.tcl:25 #, tcl-format -msgid "Run Command: %s" -msgstr "Запуск команды: %s" +msgid "Invalid date from Git: %s" +msgstr "Неправильная дата в репозитории: %s" -#: lib/tools_dlg.tcl:311 -msgid "Arguments" -msgstr "Аргументы" +#: lib/database.tcl:42 +msgid "Number of loose objects" +msgstr "Количество несвязанных объектов" -#: lib/tools_dlg.tcl:348 -msgid "OK" -msgstr "OK" +#: lib/database.tcl:43 +msgid "Disk space used by loose objects" +msgstr "Объем дискового пространства, занятый несвязанными объектами" -#: lib/transport.tcl:7 +#: lib/database.tcl:44 +msgid "Number of packed objects" +msgstr "Количество упакованных объектов" + +#: lib/database.tcl:45 +msgid "Number of packs" +msgstr "Количество pack-файлов" + +#: 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:66 #, tcl-format -msgid "Fetching new changes from %s" -msgstr "Извлечение изменений из %s " +msgid "%s (%s): Database Statistics" +msgstr "%s (%s): Статистика базы данных" -#: lib/transport.tcl:18 +#: lib/database.tcl:72 +msgid "Compressing the object database" +msgstr "Сжатие базы объектов" + +#: lib/database.tcl:83 +msgid "Verifying the object database with fsck-objects" +msgstr "Проверка базы объектов при помощи fsck" + +#: lib/database.tcl:107 #, tcl-format -msgid "remote prune %s" -msgstr "чистка внешнего %s" +msgid "" +"This repository currently has approximately %i loose objects.\n" +"\n" +"To maintain optimal performance it is strongly recommended that you compress the database.\n" +"\n" +"Compress the database now?" +msgstr "Этот репозиторий сейчас содержит примерно %i свободных объектов\n\nДля лучшей производительности рекомендуется сжать базу данных.\n\nСжать базу данных сейчас?" -#: lib/transport.tcl:19 +#: lib/error.tcl:20 #, tcl-format -msgid "Pruning tracking branches deleted from %s" -msgstr "Чистка отслеживаемых веток, удалённых из %s" +msgid "%s: error" +msgstr "%s: ошибка" -#: lib/transport.tcl:26 +#: lib/error.tcl:36 #, tcl-format -msgid "Pushing changes to %s" -msgstr "Отправка изменений в %s " +msgid "%s: warning" +msgstr "%s: предупреждение" -#: lib/transport.tcl:64 +#: lib/error.tcl:80 #, tcl-format -msgid "Mirroring to %s" -msgstr "Точное копирование в %s" +msgid "%s hook failed:" +msgstr "ошибка перехватчика %s:" -#: lib/transport.tcl:82 +#: lib/error.tcl:96 +msgid "You must correct the above errors before committing." +msgstr "Перед коммитом, исправьте вышеуказанные ошибки." + +#: lib/error.tcl:116 #, tcl-format -msgid "Pushing %s %s to %s" -msgstr "Отправка %s %s в %s" +msgid "%s (%s): error" +msgstr "%s (%s): ошибка" -#: lib/transport.tcl:100 -msgid "Push Branches" -msgstr "Отправить ветки" +#: lib/merge.tcl:13 +msgid "" +"Cannot merge while amending.\n" +"\n" +"You must finish amending this commit before starting any type of merge.\n" +msgstr "Невозможно выполнить слияние во время исправления.\n\nЗавершите исправление данного коммита перед выполнением операции слияния.\n" -#: lib/transport.tcl:114 -msgid "Source Branches" -msgstr "Исходные ветки" +#: lib/merge.tcl:27 +msgid "" +"Last scanned state does not match repository state.\n" +"\n" +"Another Git program has modified this repository since the last scan. A rescan must be performed before a merge can be performed.\n" +"\n" +"The rescan will be automatically started now.\n" +msgstr "Последнее прочитанное состояние репозитория не соответствует текущему.\n\nС момента последней проверки репозиторий был изменен другой программой Git. Необходимо перечитать репозиторий, прежде чем слияние может быть сделано.\n\nЭто будет сделано сейчас автоматически.\n" -#: lib/transport.tcl:131 -msgid "Destination Repository" -msgstr "Репозиторий назначения" +#: lib/merge.tcl:45 +#, tcl-format +msgid "" +"You are in the middle of a conflicted merge.\n" +"\n" +"File %s has merge conflicts.\n" +"\n" +"You must resolve them, stage the file, and commit to complete the current merge. Only then can you begin another merge.\n" +msgstr "Предыдущее слияние не завершено из-за конфликта.\n\nДля файла %s возник конфликт слияния.\n\nРазрешите конфликт, добавьте файл в индекс и закоммитьте. Только после этого можно начать следующее слияние.\n" -#: lib/transport.tcl:169 -msgid "Transfer Options" -msgstr "Настройки отправки" +#: lib/merge.tcl:55 +#, tcl-format +msgid "" +"You are in the middle of a change.\n" +"\n" +"File %s is modified.\n" +"\n" +"You should complete the current commit before starting a merge. Doing so will help you abort a failed merge, should the need arise.\n" +msgstr "Вы находитесь в процессе изменений.\n\nФайл %s изменён.\n\nВы должны завершить текущий коммит перед началом слияния. В случае необходимости, это позволит прервать операцию слияния.\n" -#: lib/transport.tcl:171 -msgid "Force overwrite existing branch (may discard changes)" -msgstr "Принудительно перезаписать существующую ветку (возможна потеря изменений)" +#: lib/merge.tcl:108 +#, tcl-format +msgid "%s of %s" +msgstr "%s из %s" -#: lib/transport.tcl:175 -msgid "Use thin pack (for slow network connections)" -msgstr "Использовать thin pack (для медленных сетевых подключений)" +#: lib/merge.tcl:126 +#, tcl-format +msgid "Merging %s and %s..." +msgstr "Слияние %s и %s…" -#: lib/transport.tcl:179 -msgid "Include tags" -msgstr "Передать метки" +#: 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" +"You must finish amending this commit.\n" +msgstr "Невозможно прервать исправление.\n\nЗавершите текущее исправление коммита.\n" + +#: lib/merge.tcl:228 +msgid "" +"Abort merge?\n" +"\n" +"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n" +"\n" +"Continue with aborting the current merge?" +msgstr "Прервать операцию слияния?\n\nПрерывание текущего слияния приведет к потере *ВСЕХ* несохраненных изменений.\n\nПродолжить?" + +#: lib/merge.tcl:234 +msgid "" +"Reset changes?\n" +"\n" +"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n" +"\n" +"Continue with resetting the current changes?" +msgstr "Сбросить изменения?\n\nСброс изменений приведет к потере *ВСЕХ* несохраненных изменений.\n\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 "Прервано." From a4e1bc99713355b8b11cdd8ae691aa05f063b351 Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Sat, 7 Nov 2020 14:20:39 -0800 Subject: [PATCH 04/42] git-gui: ssh-askpass: add a checkbox to show the input text Hide the input text by default since the field is commonly used for sensative informations such as passwords. Add a "Show input" checkbox to conditionally show the input. Helped-by: Miguel Boekhold Signed-off-by: Efimov Vasily Signed-off-by: David Aguilar Signed-off-by: Pratyush Yadav --- git-gui--askpass | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/git-gui--askpass b/git-gui--askpass index 1c99ee8ca2..71a536d232 100755 --- a/git-gui--askpass +++ b/git-gui--askpass @@ -26,8 +26,21 @@ pack .m -side top -fill x -padx 20 -pady 20 -expand 1 entry .e -textvariable answer -width 50 pack .e -side top -fill x -padx 10 -pady 10 +proc on_show_input_changed {args} { + global show_input + if {$show_input} { + .e configure -show "" + } else { + .e configure -show "*" + } +} +trace add variable show_input write "on_show_input_changed" + +set show_input 0 + if {!$yesno} { - .e configure -show "*" + checkbutton .cb_show -text "Show input" -variable show_input + pack .cb_show -side top -anchor nw } frame .b From aab179d937379e28c67dcab0a46fdba05c11d919 Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Thu, 3 Dec 2020 13:55:13 -0500 Subject: [PATCH 05/42] builtin/clone.c: don't ignore transport_fetch_refs() errors If 'git clone' couldn't execute 'transport_fetch_refs()' (e.g., because of an error on the remote's side in 'git upload-pack'), then it will silently ignore it. Even though this has been the case at least since clone was ported to C (way back in 8434c2f1af (Build in clone, 2008-04-27)), 'git fetch' doesn't ignore these and reports any failures it sees. That suggests that ignoring the return value in 'git clone' is simply an oversight that should be corrected. That's exactly what this patch does. (Noticing and fixing this is no coincidence, we'll want it in the next patch in order to demonstrate a regression in 'git upload-pack' via a 'git clone'.) There's no additional logging here, but that matches how 'git fetch' handles the same case. An assumption there is that whichever part of transport_fetch_refs() fails will complain loudly, so any additional logging here is redundant. Co-authored-by: Jeff King Signed-off-by: Jeff King Signed-off-by: Taylor Blau Signed-off-by: Junio C Hamano --- builtin/clone.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index a0841923cf..a5630337e4 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1293,8 +1293,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix) break; } - if (!is_local && !complete_refs_before_fetch) - transport_fetch_refs(transport, mapped_refs); + if (!is_local && !complete_refs_before_fetch) { + err = transport_fetch_refs(transport, mapped_refs); + if (err) + goto cleanup; + } remote_head = find_ref_by_name(refs, "HEAD"); remote_head_points_at = @@ -1339,8 +1342,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (is_local) clone_local(path, git_dir); - else if (refs && complete_refs_before_fetch) - transport_fetch_refs(transport, mapped_refs); + else if (refs && complete_refs_before_fetch) { + err = transport_fetch_refs(transport, mapped_refs); + if (err) + goto cleanup; + } update_remote_refs(refs, mapped_refs, remote_head_points_at, branch_top.buf, reflog_msg.buf, transport, @@ -1367,6 +1373,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) junk_mode = JUNK_LEAVE_REPO; err = checkout(submodule_progress); +cleanup: free(remote_name); strbuf_release(&reflog_msg); strbuf_release(&branch_top); From 8d133f500a5390a089988141cdec8154a732764d Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Thu, 3 Dec 2020 13:55:18 -0500 Subject: [PATCH 06/42] upload-pack.c: don't free allowed_filters util pointers To keep track of which object filters are allowed or not, 'git upload-pack' stores the name of each filter in a string_list, and sets it ->util pointer to be either 0 or 1, indicating whether it is banned or allowed. Later on, we attempt to clear that list, but we incorrectly ask for the util pointers to be free()'d, too. This behavior (introduced back in 6dd3456a8c (upload-pack.c: allow banning certain object filter(s), 2020-08-03)) leads to an invalid free, and causes us to crash. In order to trigger this, one needs to fetch from a server that (a) has at least one object filter allowed, and (b) issue a fetch that contains a subset of the allowed filters (i.e., we cannot ask for a banned filter, since this causes us to die() before we hit the bogus string_list_clear()). In that case, whatever banned filters exist will cause a noop free() (since those ->util pointers are set to 0), but the first allowed filter we try to free will crash us. We never noticed this in the tests because we didn't have an example of setting 'uploadPackFilter' configuration variables and then following up with a valid fetch. The first new 'git clone' prevents further regression here. For good measure on top, add a test which checks the same behavior at a tree depth greater than 0. Signed-off-by: Taylor Blau Signed-off-by: Junio C Hamano --- t/t5616-partial-clone.sh | 10 +++++++++- upload-pack.c | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index f4d49d8335..5da945cf15 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -281,7 +281,15 @@ test_expect_success 'upload-pack limits tree depth filters' ' test_config -C srv.bare uploadpackfilter.tree.maxDepth 0 && test_must_fail ok=sigpipe git clone --no-checkout --filter=tree:1 \ "file://$(pwd)/srv.bare" pc3 2>err && - test_i18ngrep "tree filter allows max depth 0, but got 1" err + test_i18ngrep "tree filter allows max depth 0, but got 1" err && + + git clone --no-checkout --filter=tree:0 "file://$(pwd)/srv.bare" pc4 && + + test_config -C srv.bare uploadpackfilter.tree.maxDepth 5 && + git clone --no-checkout --filter=tree:5 "file://$(pwd)/srv.bare" pc5 && + test_must_fail ok=sigpipe git clone --no-checkout --filter=tree:6 \ + "file://$(pwd)/srv.bare" pc6 2>err && + test_i18ngrep "tree filter allows max depth 5, but got 6" err ' test_expect_success 'partial clone fetches blobs pointed to by refs even if normally filtered out' ' diff --git a/upload-pack.c b/upload-pack.c index 1006bebd50..be8fffbc07 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -154,7 +154,7 @@ static void upload_pack_data_clear(struct upload_pack_data *data) string_list_clear(&data->deepen_not, 0); object_array_clear(&data->extra_edge_obj); list_objects_filter_release(&data->filter_options); - string_list_clear(&data->allowed_filters, 1); + string_list_clear(&data->allowed_filters, 0); free((char *)data->pack_objects_hook); } From fb3920fd003e14283fb480b1eb4e8495b95034c9 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 4 Dec 2020 13:48:54 -0500 Subject: [PATCH 07/42] oid-array.h: drop sha1 mention from header guard When this file was moved from sha1-array.h, we forgot to update the preprocessor header guard to match the new name. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- oid-array.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/oid-array.h b/oid-array.h index f28d322c90..2c8b64c393 100644 --- a/oid-array.h +++ b/oid-array.h @@ -1,5 +1,5 @@ -#ifndef SHA1_ARRAY_H -#define SHA1_ARRAY_H +#ifndef OID_ARRAY_H +#define OID_ARRAY_H /** * The API provides storage and manipulation of sets of object identifiers. @@ -106,4 +106,4 @@ void oid_array_filter(struct oid_array *array, for_each_oid_fn want, void *cbdata); -#endif /* SHA1_ARRAY_H */ +#endif /* OID_ARRAY_H */ From d9ca6f8d9054e3441c0f291916cbedd2d0cad15f Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 4 Dec 2020 13:49:24 -0500 Subject: [PATCH 08/42] t0064: drop sha1 mention from filename The data type is an oid_array these days, and we are using "test-tool oid-array", so let's name the test script appropriately. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/{t0064-sha1-array.sh => t0064-oid-array.sh} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename t/{t0064-sha1-array.sh => t0064-oid-array.sh} (96%) diff --git a/t/t0064-sha1-array.sh b/t/t0064-oid-array.sh similarity index 96% rename from t/t0064-sha1-array.sh rename to t/t0064-oid-array.sh index 45685af2fd..71034a8007 100755 --- a/t/t0064-sha1-array.sh +++ b/t/t0064-oid-array.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='basic tests for the SHA1 array implementation' +test_description='basic tests for the oid array implementation' . ./test-lib.sh echoid () { From 3ea922fc8b19d8cdf967ca7b3229856e6326d099 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 4 Dec 2020 13:50:23 -0500 Subject: [PATCH 09/42] t0064: make duplicate tests more robust Our tests for handling duplicates in oid-array provide only a single duplicate for each number, so our sorted array looks like: 44 44 55 55 88 88 aa aa A slightly more interesting test is to have multiple duplicates, which makes sure that we not only skip the duplicate, but keep skipping until we are out of the set of matching duplicates. Unsurprisingly this works just fine, but it's worth beefing up this test since we're about to change the duplicate-detection code. Note that we do need to adjust the results on the lookup test, since it is returning the index of the found item (and now we have more items before our range, and the range itself is slightly larger, since we'll accept a match of any element). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/t0064-oid-array.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/t/t0064-oid-array.sh b/t/t0064-oid-array.sh index 71034a8007..2e5438ccda 100755 --- a/t/t0064-oid-array.sh +++ b/t/t0064-oid-array.sh @@ -25,6 +25,7 @@ test_expect_success 'ordered enumeration' ' test_expect_success 'ordered enumeration with duplicate suppression' ' echoid "" 44 55 88 aa >expect && { + echoid append 88 44 aa 55 && echoid append 88 44 aa 55 && echoid append 88 44 aa 55 && echo for_each_unique @@ -52,17 +53,19 @@ test_expect_success 'lookup non-existing entry' ' test_expect_success 'lookup with duplicates' ' { + echoid append 88 44 aa 55 && echoid append 88 44 aa 55 && echoid append 88 44 aa 55 && echoid lookup 55 } | test-tool oid-array >actual && n=$(cat actual) && - test "$n" -ge 2 && - test "$n" -le 3 + test "$n" -ge 3 && + test "$n" -le 5 ' test_expect_success 'lookup non-existing entry with duplicates' ' { + echoid append 88 44 aa 55 && echoid append 88 44 aa 55 && echoid append 88 44 aa 55 && echoid lookup 66 From 3fa6f2aa57e997ff2e665d83335a8f1078b94cb8 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 4 Dec 2020 13:51:39 -0500 Subject: [PATCH 10/42] cache.h: move hash/oid functions to hash.h We define git_hash_algo and object_id in hash.h, but most of the utility functions are declared in the main cache.h. Let's move them to hash.h along with their struct definitions. This cleans up cache.h a bit, but also avoids circular dependencies when other headers need to know about these functions (e.g., if oid-array.h were to have an inline that used oideq(), it couldn't include cache.h because it is itself included by cache.h). No including C files should be affected, because hash.h is always included in cache.h already. We do have to mention repository.h at the top of hash.h, though, since we depend on the_repository in some of our inline functions. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 94 -------------------------------------------------------- hash.h | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 94 deletions(-) diff --git a/cache.h b/cache.h index e986cf4ea9..ec98f5d32c 100644 --- a/cache.h +++ b/cache.h @@ -1123,100 +1123,6 @@ const char *repo_find_unique_abbrev(struct repository *r, const struct object_id int repo_find_unique_abbrev_r(struct repository *r, char *hex, const struct object_id *oid, int len); #define find_unique_abbrev_r(hex, oid, len) repo_find_unique_abbrev_r(the_repository, hex, oid, len) -extern const struct object_id null_oid; - -static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2) -{ - /* - * Teach the compiler that there are only two possibilities of hash size - * here, so that it can optimize for this case as much as possible. - */ - if (the_hash_algo->rawsz == GIT_MAX_RAWSZ) - return memcmp(sha1, sha2, GIT_MAX_RAWSZ); - return memcmp(sha1, sha2, GIT_SHA1_RAWSZ); -} - -static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2) -{ - return hashcmp(oid1->hash, oid2->hash); -} - -static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2) -{ - /* - * We write this here instead of deferring to hashcmp so that the - * compiler can properly inline it and avoid calling memcmp. - */ - if (the_hash_algo->rawsz == GIT_MAX_RAWSZ) - return !memcmp(sha1, sha2, GIT_MAX_RAWSZ); - return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ); -} - -static inline int oideq(const struct object_id *oid1, const struct object_id *oid2) -{ - return hasheq(oid1->hash, oid2->hash); -} - -static inline int is_null_oid(const struct object_id *oid) -{ - return oideq(oid, &null_oid); -} - -static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src) -{ - memcpy(sha_dst, sha_src, the_hash_algo->rawsz); -} - -static inline void oidcpy(struct object_id *dst, const struct object_id *src) -{ - memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ); -} - -static inline struct object_id *oiddup(const struct object_id *src) -{ - struct object_id *dst = xmalloc(sizeof(struct object_id)); - oidcpy(dst, src); - return dst; -} - -static inline void hashclr(unsigned char *hash) -{ - memset(hash, 0, the_hash_algo->rawsz); -} - -static inline void oidclr(struct object_id *oid) -{ - memset(oid->hash, 0, GIT_MAX_RAWSZ); -} - -static inline void oidread(struct object_id *oid, const unsigned char *hash) -{ - memcpy(oid->hash, hash, the_hash_algo->rawsz); -} - -static inline int is_empty_blob_sha1(const unsigned char *sha1) -{ - return hasheq(sha1, the_hash_algo->empty_blob->hash); -} - -static inline int is_empty_blob_oid(const struct object_id *oid) -{ - return oideq(oid, the_hash_algo->empty_blob); -} - -static inline int is_empty_tree_sha1(const unsigned char *sha1) -{ - return hasheq(sha1, the_hash_algo->empty_tree->hash); -} - -static inline int is_empty_tree_oid(const struct object_id *oid) -{ - return oideq(oid, the_hash_algo->empty_tree); -} - -const char *empty_tree_oid_hex(void); -const char *empty_blob_oid_hex(void); - /* set default permissions by passing mode arguments to open(2) */ int git_mkstemps_mode(char *pattern, int suffix_len, int mode); int git_mkstemp_mode(char *pattern, int mode); diff --git a/hash.h b/hash.h index e0f3f16b06..3fb0c3d400 100644 --- a/hash.h +++ b/hash.h @@ -2,6 +2,7 @@ #define HASH_H #include "git-compat-util.h" +#include "repository.h" #if defined(SHA1_PPC) #include "ppc/sha1.h" @@ -184,4 +185,98 @@ struct object_id { #define the_hash_algo the_repository->hash_algo +extern const struct object_id null_oid; + +static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2) +{ + /* + * Teach the compiler that there are only two possibilities of hash size + * here, so that it can optimize for this case as much as possible. + */ + if (the_hash_algo->rawsz == GIT_MAX_RAWSZ) + return memcmp(sha1, sha2, GIT_MAX_RAWSZ); + return memcmp(sha1, sha2, GIT_SHA1_RAWSZ); +} + +static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2) +{ + return hashcmp(oid1->hash, oid2->hash); +} + +static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2) +{ + /* + * We write this here instead of deferring to hashcmp so that the + * compiler can properly inline it and avoid calling memcmp. + */ + if (the_hash_algo->rawsz == GIT_MAX_RAWSZ) + return !memcmp(sha1, sha2, GIT_MAX_RAWSZ); + return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ); +} + +static inline int oideq(const struct object_id *oid1, const struct object_id *oid2) +{ + return hasheq(oid1->hash, oid2->hash); +} + +static inline int is_null_oid(const struct object_id *oid) +{ + return oideq(oid, &null_oid); +} + +static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src) +{ + memcpy(sha_dst, sha_src, the_hash_algo->rawsz); +} + +static inline void oidcpy(struct object_id *dst, const struct object_id *src) +{ + memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ); +} + +static inline struct object_id *oiddup(const struct object_id *src) +{ + struct object_id *dst = xmalloc(sizeof(struct object_id)); + oidcpy(dst, src); + return dst; +} + +static inline void hashclr(unsigned char *hash) +{ + memset(hash, 0, the_hash_algo->rawsz); +} + +static inline void oidclr(struct object_id *oid) +{ + memset(oid->hash, 0, GIT_MAX_RAWSZ); +} + +static inline void oidread(struct object_id *oid, const unsigned char *hash) +{ + memcpy(oid->hash, hash, the_hash_algo->rawsz); +} + +static inline int is_empty_blob_sha1(const unsigned char *sha1) +{ + return hasheq(sha1, the_hash_algo->empty_blob->hash); +} + +static inline int is_empty_blob_oid(const struct object_id *oid) +{ + return oideq(oid, the_hash_algo->empty_blob); +} + +static inline int is_empty_tree_sha1(const unsigned char *sha1) +{ + return hasheq(sha1, the_hash_algo->empty_tree->hash); +} + +static inline int is_empty_tree_oid(const struct object_id *oid) +{ + return oideq(oid, the_hash_algo->empty_tree); +} + +const char *empty_tree_oid_hex(void); +const char *empty_blob_oid_hex(void); + #endif From d0482b445bb4c22a3f866c849835e366ec0b14a7 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 4 Dec 2020 13:52:07 -0500 Subject: [PATCH 11/42] oid-array: make sort function public We sort the oid-array as a side effect of calling the lookup or unique-iteration functions. But callers may want to sort it themselves (especially as we add new iteration options in future patches). We'll also move the check of the "sorted" flag into the sort function, so callers don't have to remember to check it. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- oid-array.c | 10 +++++----- oid-array.h | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/oid-array.c b/oid-array.c index 8657a5cedf..29f718d835 100644 --- a/oid-array.c +++ b/oid-array.c @@ -14,8 +14,10 @@ static int void_hashcmp(const void *a, const void *b) return oidcmp(a, b); } -static void oid_array_sort(struct oid_array *array) +void oid_array_sort(struct oid_array *array) { + if (array->sorted) + return; QSORT(array->oid, array->nr, void_hashcmp); array->sorted = 1; } @@ -28,8 +30,7 @@ static const unsigned char *sha1_access(size_t index, void *table) int oid_array_lookup(struct oid_array *array, const struct object_id *oid) { - if (!array->sorted) - oid_array_sort(array); + oid_array_sort(array); return sha1_pos(oid->hash, array->oid, array->nr, sha1_access); } @@ -64,8 +65,7 @@ int oid_array_for_each_unique(struct oid_array *array, { size_t i; - if (!array->sorted) - oid_array_sort(array); + oid_array_sort(array); for (i = 0; i < array->nr; i++) { int ret; diff --git a/oid-array.h b/oid-array.h index 2c8b64c393..6a22c0ac94 100644 --- a/oid-array.h +++ b/oid-array.h @@ -106,4 +106,9 @@ void oid_array_filter(struct oid_array *array, for_each_oid_fn want, void *cbdata); +/** + * Sort the array in order of ascending object id. + */ +void oid_array_sort(struct oid_array *array); + #endif /* OID_ARRAY_H */ From 8f19c9fd433c02ee1496bc6f34ef0a061c3f2087 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 6 Dec 2020 13:15:59 +0000 Subject: [PATCH 12/42] t6300: avoid using the default name of the initial branch Our test suite currently only passes when `git init` uses the name `master` for the initial branch. This would stop us from changing the default branch name. Let's adjust t6300 so that it does not rely on any specific default branch name. This trick is done by (force-)renaming the initial branch to the name `main` in the `setup` and the `:remotename and :remoteref` test cases, and then replacing all mentions of `master` and `MASTER` with `main` and `MAIN`, respectively. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t6300-for-each-ref.sh | 178 ++++++++++++++++++++-------------------- 1 file changed, 90 insertions(+), 88 deletions(-) diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index b359023189..810cdbb6f8 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -28,12 +28,13 @@ test_expect_success setup ' echo "Using $datestamp" > one && git add one && git commit -m "Initial" && + git branch -M main && setdate_and_increment && git tag -a -m "Tagging at $datestamp" testtag && - git update-ref refs/remotes/origin/master master && + git update-ref refs/remotes/origin/main main && git remote add origin nowhere && - git config branch.master.remote origin && - git config branch.master.merge refs/heads/master && + git config branch.main.remote origin && + git config branch.main.merge refs/heads/main && git remote add myfork elsewhere && git config remote.pushdefault myfork && git config push.default current @@ -41,7 +42,7 @@ test_expect_success setup ' test_atom() { case "$1" in - head) ref=refs/heads/master ;; + head) ref=refs/heads/main ;; tag) ref=refs/tags/testtag ;; sym) ref=refs/heads/sym ;; *) ref=$1 ;; @@ -76,49 +77,49 @@ test_atom() { hexlen=$(test_oid hexsz) disklen=$(test_oid disklen) -test_atom head refname refs/heads/master -test_atom head refname: refs/heads/master -test_atom head refname:short master -test_atom head refname:lstrip=1 heads/master -test_atom head refname:lstrip=2 master -test_atom head refname:lstrip=-1 master -test_atom head refname:lstrip=-2 heads/master +test_atom head refname refs/heads/main +test_atom head refname: refs/heads/main +test_atom head refname:short main +test_atom head refname:lstrip=1 heads/main +test_atom head refname:lstrip=2 main +test_atom head refname:lstrip=-1 main +test_atom head refname:lstrip=-2 heads/main test_atom head refname:rstrip=1 refs/heads test_atom head refname:rstrip=2 refs test_atom head refname:rstrip=-1 refs test_atom head refname:rstrip=-2 refs/heads -test_atom head refname:strip=1 heads/master -test_atom head refname:strip=2 master -test_atom head refname:strip=-1 master -test_atom head refname:strip=-2 heads/master -test_atom head upstream refs/remotes/origin/master -test_atom head upstream:short origin/master -test_atom head upstream:lstrip=2 origin/master -test_atom head upstream:lstrip=-2 origin/master +test_atom head refname:strip=1 heads/main +test_atom head refname:strip=2 main +test_atom head refname:strip=-1 main +test_atom head refname:strip=-2 heads/main +test_atom head upstream refs/remotes/origin/main +test_atom head upstream:short origin/main +test_atom head upstream:lstrip=2 origin/main +test_atom head upstream:lstrip=-2 origin/main test_atom head upstream:rstrip=2 refs/remotes test_atom head upstream:rstrip=-2 refs/remotes -test_atom head upstream:strip=2 origin/master -test_atom head upstream:strip=-2 origin/master -test_atom head push refs/remotes/myfork/master -test_atom head push:short myfork/master -test_atom head push:lstrip=1 remotes/myfork/master -test_atom head push:lstrip=-1 master +test_atom head upstream:strip=2 origin/main +test_atom head upstream:strip=-2 origin/main +test_atom head push refs/remotes/myfork/main +test_atom head push:short myfork/main +test_atom head push:lstrip=1 remotes/myfork/main +test_atom head push:lstrip=-1 main test_atom head push:rstrip=1 refs/remotes/myfork test_atom head push:rstrip=-1 refs -test_atom head push:strip=1 remotes/myfork/master -test_atom head push:strip=-1 master +test_atom head push:strip=1 remotes/myfork/main +test_atom head push:strip=-1 main test_atom head objecttype commit test_atom head objectsize $((131 + hexlen)) test_atom head objectsize:disk $disklen test_atom head deltabase $ZERO_OID -test_atom head objectname $(git rev-parse refs/heads/master) -test_atom head objectname:short $(git rev-parse --short refs/heads/master) -test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/master) -test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/master) -test_atom head tree $(git rev-parse refs/heads/master^{tree}) -test_atom head tree:short $(git rev-parse --short refs/heads/master^{tree}) -test_atom head tree:short=1 $(git rev-parse --short=1 refs/heads/master^{tree}) -test_atom head tree:short=10 $(git rev-parse --short=10 refs/heads/master^{tree}) +test_atom head objectname $(git rev-parse refs/heads/main) +test_atom head objectname:short $(git rev-parse --short refs/heads/main) +test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) +test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) +test_atom head tree $(git rev-parse refs/heads/main^{tree}) +test_atom head tree:short $(git rev-parse --short refs/heads/main^{tree}) +test_atom head tree:short=1 $(git rev-parse --short=1 refs/heads/main^{tree}) +test_atom head tree:short=10 $(git rev-parse --short=10 refs/heads/main^{tree}) test_atom head parent '' test_atom head parent:short '' test_atom head parent:short=1 '' @@ -171,8 +172,8 @@ test_atom tag deltabase $ZERO_OID test_atom tag '*deltabase' $ZERO_OID test_atom tag objectname $(git rev-parse refs/tags/testtag) test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag) -test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/master) -test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/master) +test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) +test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) test_atom tag tree '' test_atom tag tree:short '' test_atom tag tree:short=1 '' @@ -253,7 +254,7 @@ test_date () { author_date=$3 && tagger_date=$4 && cat >expected <<-EOF && - 'refs/heads/master' '$committer_date' '$author_date' + 'refs/heads/main' '$committer_date' '$author_date' 'refs/tags/testtag' '$tagger_date' EOF ( @@ -375,8 +376,8 @@ test_expect_success 'exercise strftime with odd fields' ' ' cat >expected <<\EOF -refs/heads/master -refs/remotes/origin/master +refs/heads/main +refs/remotes/origin/main refs/tags/testtag EOF @@ -388,8 +389,8 @@ test_expect_success 'Verify ascending sort' ' cat >expected <<\EOF refs/tags/testtag -refs/remotes/origin/master -refs/heads/master +refs/remotes/origin/main +refs/heads/main EOF test_expect_success 'Verify descending sort' ' @@ -424,8 +425,8 @@ test_expect_success 'exercise glob patterns with prefixes' ' ' cat >expected <<\EOF -'refs/heads/master' -'refs/remotes/origin/master' +'refs/heads/main' +'refs/remotes/origin/main' 'refs/tags/testtag' EOF @@ -445,8 +446,8 @@ test_expect_success 'Quoting style: python' ' ' cat >expected <<\EOF -"refs/heads/master" -"refs/remotes/origin/master" +"refs/heads/main" +"refs/remotes/origin/main" "refs/tags/testtag" EOF @@ -473,8 +474,8 @@ test_atom head upstream:nobracket,track 'ahead 1' test_expect_success 'setup for push:track[short]' ' test_commit third && - git update-ref refs/remotes/myfork/master master && - git reset master~1 + git update-ref refs/remotes/myfork/main main && + git reset main~1 ' test_atom head push:track '[behind 1]' @@ -490,8 +491,8 @@ test_expect_success 'Check that :track[short] works when upstream is invalid' ' [gone] EOF - test_when_finished "git config branch.master.merge refs/heads/master" && - git config branch.master.merge refs/heads/does-not-exist && + test_when_finished "git config branch.main.merge refs/heads/main" && + git config branch.main.merge refs/heads/does-not-exist && git for-each-ref \ --format="%(upstream:track)$LF%(upstream:trackshort)" \ refs/heads >actual && @@ -504,9 +505,9 @@ test_expect_success 'Check for invalid refname format' ' test_expect_success 'set up color tests' ' cat >expected.color <<-EOF && - $(git rev-parse --short refs/heads/master) master - $(git rev-parse --short refs/remotes/myfork/master) myfork/master - $(git rev-parse --short refs/remotes/origin/master) origin/master + $(git rev-parse --short refs/heads/main) main + $(git rev-parse --short refs/remotes/myfork/main) myfork/main + $(git rev-parse --short refs/remotes/origin/main) origin/main $(git rev-parse --short refs/tags/testtag) testtag $(git rev-parse --short refs/tags/third) third $(git rev-parse --short refs/tags/two) two @@ -538,8 +539,8 @@ test_expect_success 'color.ui=always does not override tty check' ' ' cat >expected <<\EOF -heads/master -tags/master +heads/main +tags/main EOF test_expect_success 'Check ambiguous head and tag refs (strict)' ' @@ -549,19 +550,19 @@ test_expect_success 'Check ambiguous head and tag refs (strict)' ' git add one && git commit -m "Branch" && setdate_and_increment && - git tag -m "Tagging at $datestamp" master && - git for-each-ref --format "%(refname:short)" refs/heads/master refs/tags/master >actual && + git tag -m "Tagging at $datestamp" main && + git for-each-ref --format "%(refname:short)" refs/heads/main refs/tags/main >actual && test_cmp expected actual ' cat >expected <<\EOF -heads/master -master +heads/main +main EOF test_expect_success 'Check ambiguous head and tag refs (loose)' ' git config --bool core.warnambiguousrefs false && - git for-each-ref --format "%(refname:short)" refs/heads/master refs/tags/master >actual && + git for-each-ref --format "%(refname:short)" refs/heads/main refs/tags/main >actual && test_cmp expected actual ' @@ -571,7 +572,7 @@ ambiguous EOF test_expect_success 'Check ambiguous head and tag refs II (loose)' ' - git checkout master && + git checkout main && git tag ambiguous testtag^0 && git branch ambiguous testtag^0 && git for-each-ref --format "%(refname:short)" refs/heads/ambiguous refs/tags/ambiguous >actual && @@ -705,8 +706,8 @@ body contents $sig" test_expect_success 'set up refs pointing to tree and blob' ' - git update-ref refs/mytrees/first refs/heads/master^{tree} && - git update-ref refs/myblobs/first refs/heads/master:one + git update-ref refs/mytrees/first refs/heads/main^{tree} && + git update-ref refs/myblobs/first refs/heads/main:one ' test_atom refs/mytrees/first subject "" @@ -778,7 +779,7 @@ test_expect_success 'equivalent sorts fall back on refname' ' ' test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' ' - test_when_finished "git checkout master" && + test_when_finished "git checkout main" && git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual && sed -e "s/^\* / /" actual >expect && git checkout --orphan orphaned-branch && @@ -815,9 +816,9 @@ test_expect_success '%(trailers:unfold) unfolds trailers' ' unfold expect && - git for-each-ref --format="%(trailers:unfold)" refs/heads/master >actual && + git for-each-ref --format="%(trailers:unfold)" refs/heads/main >actual && test_cmp expect actual && - git for-each-ref --format="%(contents:trailers:unfold)" refs/heads/master >actual && + git for-each-ref --format="%(contents:trailers:unfold)" refs/heads/main >actual && test_cmp expect actual ' @@ -826,9 +827,9 @@ test_expect_success '%(trailers:only) shows only "key: value" trailers' ' grep -v patch.description expect && - git for-each-ref --format="%(trailers:only)" refs/heads/master >actual && + git for-each-ref --format="%(trailers:only)" refs/heads/main >actual && test_cmp expect actual && - git for-each-ref --format="%(contents:trailers:only)" refs/heads/master >actual && + git for-each-ref --format="%(contents:trailers:only)" refs/heads/main >actual && test_cmp expect actual ' @@ -837,13 +838,13 @@ test_expect_success '%(trailers:only) and %(trailers:unfold) work together' ' grep -v patch.description expect && - git for-each-ref --format="%(trailers:only,unfold)" refs/heads/master >actual && + git for-each-ref --format="%(trailers:only,unfold)" refs/heads/main >actual && test_cmp expect actual && - git for-each-ref --format="%(trailers:unfold,only)" refs/heads/master >actual && + git for-each-ref --format="%(trailers:unfold,only)" refs/heads/main >actual && test_cmp actual actual && - git for-each-ref --format="%(contents:trailers:only,unfold)" refs/heads/master >actual && + git for-each-ref --format="%(contents:trailers:only,unfold)" refs/heads/main >actual && test_cmp expect actual && - git for-each-ref --format="%(contents:trailers:unfold,only)" refs/heads/master >actual && + git for-each-ref --format="%(contents:trailers:unfold,only)" refs/heads/main >actual && test_cmp actual actual ' @@ -867,7 +868,7 @@ test_expect_success 'if arguments, %(contents:trailers) shows error if colon is ' test_expect_success 'basic atom: head contents:trailers' ' - git for-each-ref --format="%(contents:trailers)" refs/heads/master >actual && + git for-each-ref --format="%(contents:trailers)" refs/heads/main >actual && sanitize_pgp actual.clean && # git for-each-ref ends with a blank line cat >expect <<-EOF && @@ -896,16 +897,16 @@ test_expect_success 'trailer parsing not fooled by --- line' ' echo "trailer: right" && echo } >expect && - git for-each-ref --format="%(trailers)" refs/heads/master >actual && + git for-each-ref --format="%(trailers)" refs/heads/main >actual && test_cmp expect actual ' test_expect_success 'Add symbolic ref for the following tests' ' - git symbolic-ref refs/heads/sym refs/heads/master + git symbolic-ref refs/heads/sym refs/heads/main ' cat >expected <expected <expected <expect && git for-each-ref --format="${pair%=*}" \ - refs/heads/master >actual && + refs/heads/main >actual && test_cmp expect actual done && git branch push-simple && @@ -981,12 +983,12 @@ test_expect_success ':remotename and :remoteref' ' ' test_expect_success 'for-each-ref --ignore-case ignores case' ' - git for-each-ref --format="%(refname)" refs/heads/MASTER >actual && + git for-each-ref --format="%(refname)" refs/heads/MAIN >actual && test_must_be_empty actual && - echo refs/heads/master >expect && + echo refs/heads/main >expect && git for-each-ref --format="%(refname)" --ignore-case \ - refs/heads/MASTER >actual && + refs/heads/MAIN >actual && test_cmp expect actual ' From 12c4b4ce754640ac565f8b9b6f072bc10fbed5af Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Dec 2020 14:11:00 -0500 Subject: [PATCH 13/42] oid-array: provide a for-loop iterator We provide oid_array_for_each_unique() for iterating over the de-duplicated items in an array. But it's awkward to use for two reasons: 1. It uses a callback, which means marshaling arguments into a struct and passing it to the callback with a void parameter. 2. The callback doesn't know the numeric index of the oid we're looking at. This is useful for things like progress meters. Iterating with a for-loop is much more natural for some cases, but the caller has to do the de-duping itself. However, we can provide a small helper to make this easier (see the docstring in the header for an example use). The caller does have to remember to sort the array first. We could add an assertion into the helper that array->sorted is set, but I didn't want to complicate what is otherwise a pretty fast code path. I also considered adding a full iterator type with init/next/end functions (similar to what we have for hashmaps). But it ended up making the callers much harder to read. This version keeps us close to a basic for-loop. Yet another option would be adding an option to sort the array and compact out the duplicates. This would mean iterating over the array an extra time, though that's probably not a big deal (we did just do an O(n log n) sort). But we'd still have to write a for-loop to iterate, so it doesn't really make anything easier for the caller. No new test, since we'll convert the callback iterator (which is covered by t0064, among other callers) to use the new code. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- oid-array.c | 7 ++----- oid-array.h | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/oid-array.c b/oid-array.c index 29f718d835..8e1bcedc0c 100644 --- a/oid-array.c +++ b/oid-array.c @@ -67,11 +67,8 @@ int oid_array_for_each_unique(struct oid_array *array, oid_array_sort(array); - for (i = 0; i < array->nr; i++) { - int ret; - if (i > 0 && oideq(array->oid + i, array->oid + i - 1)) - continue; - ret = fn(array->oid + i, data); + for (i = 0; i < array->nr; i = oid_array_next_unique(array, i)) { + int ret = fn(array->oid + i, data); if (ret) return ret; } diff --git a/oid-array.h b/oid-array.h index 6a22c0ac94..72bca78b7d 100644 --- a/oid-array.h +++ b/oid-array.h @@ -1,6 +1,8 @@ #ifndef OID_ARRAY_H #define OID_ARRAY_H +#include "hash.h" + /** * The API provides storage and manipulation of sets of object identifiers. * The emphasis is on storage and processing efficiency, making them suitable @@ -111,4 +113,25 @@ void oid_array_filter(struct oid_array *array, */ void oid_array_sort(struct oid_array *array); +/** + * Find the next unique oid in the array after position "cur". + * The array must be sorted for this to work. You can iterate + * over unique elements like this: + * + * size_t i; + * oid_array_sort(array); + * for (i = 0; i < array->nr; i = oid_array_next_unique(array, i)) + * printf("%s", oid_to_hex(array->oids[i]); + * + * Non-unique iteration can just increment with "i++" to visit each element. + */ +static inline size_t oid_array_next_unique(struct oid_array *array, size_t cur) +{ + do { + cur++; + } while (cur < array->nr && + oideq(array->oid + cur, array->oid + cur - 1)); + return cur; +} + #endif /* OID_ARRAY_H */ From 1cbdbf3bef7e9167794cb2c12f9af1a450584ebe Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Dec 2020 14:11:02 -0500 Subject: [PATCH 14/42] commit-graph: drop count_distinct_commits() function When writing a commit graph, we collect a list of object ids in an array, which we'll eventually copy into an array of "struct commit" pointers. Before we do that, though, we count the number of distinct commit entries. There's a subtle bug in this step, though. We eliminate not only duplicate oids, but also in split mode, any oids which are not commits or which are already in a graph file. However, the loop starts at index 1, always counting index 0 as distinct. And indeed it can't be a duplicate, since we check for those by comparing against the previous entry, and there isn't one for index 0. But it could be a commit that's already in a graph file, and we'd overcount the number of commits by 1 in that case. That turns out not to be a problem, though. The only things we do with the count are: - check if our count will overflow our data structures. But the limit there is 2^31 commits, so while this is a useful check, the off-by-one is not likely to matter. - pre-allocate the array of commit pointers. But over-allocating by one isn't a problem; we'll just waste a few extra bytes. The bug would be easy enough to fix, but we can observe that neither of those steps is necessary. After building the actual commit array, we'll likewise check its count for overflow. So the extra check of the distinct commit count here is redundant. And likewise we use ALLOC_GROW() when building the commit array, so there's no need to preallocate it (it's possible that doing so is slightly more efficient, but if we care we can just optimistically allocate one slot for each oid; I didn't bother here). So count_distinct_commits() isn't doing anything useful. Let's just get rid of that step. Note that a side effect of the function was that we sorted the list of oids, which we do rely on in copy_oids_to_commits(), since it must also skip the duplicates. So we'll move the qsort there. I didn't copy the "TODO" about adding more progress meters. It's actually quite hard to make a repository large enough for this qsort would take an appreciable amount of time, so this doesn't seem like a useful note. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- commit-graph.c | 43 ++----------------------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/commit-graph.c b/commit-graph.c index 6f62a07313..1ac3516cf5 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1588,35 +1588,6 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx) stop_progress(&ctx->progress); } -static uint32_t count_distinct_commits(struct write_commit_graph_context *ctx) -{ - uint32_t i, count_distinct = 1; - - if (ctx->report_progress) - ctx->progress = start_delayed_progress( - _("Counting distinct commits in commit graph"), - ctx->oids.nr); - display_progress(ctx->progress, 0); /* TODO: Measure QSORT() progress */ - QSORT(ctx->oids.list, ctx->oids.nr, oid_compare); - - for (i = 1; i < ctx->oids.nr; i++) { - display_progress(ctx->progress, i + 1); - if (!oideq(&ctx->oids.list[i - 1], &ctx->oids.list[i])) { - if (ctx->split) { - struct commit *c = lookup_commit(ctx->r, &ctx->oids.list[i]); - - if (!c || commit_graph_position(c) != COMMIT_NOT_FROM_GRAPH) - continue; - } - - count_distinct++; - } - } - stop_progress(&ctx->progress); - - return count_distinct; -} - static void copy_oids_to_commits(struct write_commit_graph_context *ctx) { uint32_t i; @@ -1628,6 +1599,7 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx) ctx->progress = start_delayed_progress( _("Finding extra edges in commit graph"), ctx->oids.nr); + QSORT(ctx->oids.list, ctx->oids.nr, oid_compare); for (i = 0; i < ctx->oids.nr; i++) { unsigned int num_parents; @@ -2155,7 +2127,7 @@ int write_commit_graph(struct object_directory *odb, const struct commit_graph_opts *opts) { struct write_commit_graph_context *ctx; - uint32_t i, count_distinct = 0; + uint32_t i; int res = 0; int replace = 0; struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS; @@ -2268,17 +2240,6 @@ int write_commit_graph(struct object_directory *odb, close_reachable(ctx); - count_distinct = count_distinct_commits(ctx); - - if (count_distinct >= GRAPH_EDGE_LAST_MASK) { - error(_("the commit graph format cannot write %d commits"), count_distinct); - res = -1; - goto cleanup; - } - - ctx->commits.alloc = count_distinct; - ALLOC_ARRAY(ctx->commits.list, ctx->commits.alloc); - copy_oids_to_commits(ctx); if (ctx->commits.nr >= GRAPH_EDGE_LAST_MASK) { From a5f1c448998fba5f5a1b00e1b9a779176ec665a6 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Dec 2020 14:11:05 -0500 Subject: [PATCH 15/42] commit-graph: replace packed_oid_list with oid_array Our custom packed_oid_list data structure is really just an oid_array in disguise. Let's switch to using the generic structure, which shortens and simplifies the code slightly. There's one slightly awkward part: in the old code we copied a hash straight from the mmap'd on-disk data into the final object_id. And now we'll copy to a temporary oid, which we'll then pass to oid_array_append(). But this is an operation we have to do all over the commit-graph code already, since it mostly uses object_id structs internally. I also measured "git commit-graph --append", which triggers this code path, and it showed no difference. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- commit-graph.c | 62 ++++++++++++-------------------------------------- 1 file changed, 15 insertions(+), 47 deletions(-) diff --git a/commit-graph.c b/commit-graph.c index 1ac3516cf5..4a718fd6e6 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -936,17 +936,11 @@ struct packed_commit_list { int alloc; }; -struct packed_oid_list { - struct object_id *list; - int nr; - int alloc; -}; - struct write_commit_graph_context { struct repository *r; struct object_directory *odb; char *graph_name; - struct packed_oid_list oids; + struct oid_array oids; struct packed_commit_list commits; int num_extra_edges; unsigned long approx_nr_objects; @@ -1240,13 +1234,6 @@ static int write_graph_chunk_bloom_data(struct hashfile *f, return 0; } -static int oid_compare(const void *_a, const void *_b) -{ - const struct object_id *a = (const struct object_id *)_a; - const struct object_id *b = (const struct object_id *)_b; - return oidcmp(a, b); -} - static int add_packed_commits(const struct object_id *oid, struct packed_git *pack, uint32_t pos, @@ -1267,10 +1254,7 @@ static int add_packed_commits(const struct object_id *oid, if (type != OBJ_COMMIT) return 0; - ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc); - oidcpy(&(ctx->oids.list[ctx->oids.nr]), oid); - ctx->oids.nr++; - + oid_array_append(&ctx->oids, oid); set_commit_pos(ctx->r, oid); return 0; @@ -1281,9 +1265,7 @@ static void add_missing_parents(struct write_commit_graph_context *ctx, struct c struct commit_list *parent; for (parent = commit->parents; parent; parent = parent->next) { if (!(parent->item->object.flags & REACHABLE)) { - ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc); - oidcpy(&ctx->oids.list[ctx->oids.nr], &(parent->item->object.oid)); - ctx->oids.nr++; + oid_array_append(&ctx->oids, &parent->item->object.oid); parent->item->object.flags |= REACHABLE; } } @@ -1302,7 +1284,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) ctx->oids.nr); for (i = 0; i < ctx->oids.nr; i++) { display_progress(ctx->progress, i + 1); - commit = lookup_commit(ctx->r, &ctx->oids.list[i]); + commit = lookup_commit(ctx->r, &ctx->oids.oid[i]); if (commit) commit->object.flags |= REACHABLE; } @@ -1319,7 +1301,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) 0); for (i = 0; i < ctx->oids.nr; i++) { display_progress(ctx->progress, i + 1); - commit = lookup_commit(ctx->r, &ctx->oids.list[i]); + commit = lookup_commit(ctx->r, &ctx->oids.oid[i]); if (!commit) continue; @@ -1339,7 +1321,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) ctx->oids.nr); for (i = 0; i < ctx->oids.nr; i++) { display_progress(ctx->progress, i + 1); - commit = lookup_commit(ctx->r, &ctx->oids.list[i]); + commit = lookup_commit(ctx->r, &ctx->oids.oid[i]); if (commit) commit->object.flags &= ~REACHABLE; @@ -1567,9 +1549,7 @@ static int fill_oids_from_commits(struct write_commit_graph_context *ctx, oidset_iter_init(commits, &iter); while ((oid = oidset_iter_next(&iter))) { - ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc); - oidcpy(&ctx->oids.list[ctx->oids.nr], oid); - ctx->oids.nr++; + oid_array_append(&ctx->oids, oid); } return 0; @@ -1599,16 +1579,14 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx) ctx->progress = start_delayed_progress( _("Finding extra edges in commit graph"), ctx->oids.nr); - QSORT(ctx->oids.list, ctx->oids.nr, oid_compare); - for (i = 0; i < ctx->oids.nr; i++) { + oid_array_sort(&ctx->oids); + for (i = 0; i < ctx->oids.nr; i = oid_array_next_unique(&ctx->oids, i)) { unsigned int num_parents; display_progress(ctx->progress, i + 1); - if (i > 0 && oideq(&ctx->oids.list[i - 1], &ctx->oids.list[i])) - continue; ALLOC_GROW(ctx->commits.list, ctx->commits.nr + 1, ctx->commits.alloc); - ctx->commits.list[ctx->commits.nr] = lookup_commit(ctx->r, &ctx->oids.list[i]); + ctx->commits.list[ctx->commits.nr] = lookup_commit(ctx->r, &ctx->oids.oid[i]); if (ctx->split && flags != COMMIT_GRAPH_SPLIT_REPLACE && commit_graph_position(ctx->commits.list[ctx->commits.nr]) != COMMIT_NOT_FROM_GRAPH) @@ -2199,26 +2177,16 @@ int write_commit_graph(struct object_directory *odb, } ctx->approx_nr_objects = approximate_object_count(); - ctx->oids.alloc = ctx->approx_nr_objects / 32; - if (ctx->split && opts && ctx->oids.alloc > opts->max_commits) - ctx->oids.alloc = opts->max_commits; - - if (ctx->append) { + if (ctx->append) prepare_commit_graph_one(ctx->r, ctx->odb); - if (ctx->r->objects->commit_graph) - ctx->oids.alloc += ctx->r->objects->commit_graph->num_commits; - } - - if (ctx->oids.alloc < 1024) - ctx->oids.alloc = 1024; - ALLOC_ARRAY(ctx->oids.list, ctx->oids.alloc); if (ctx->append && ctx->r->objects->commit_graph) { struct commit_graph *g = ctx->r->objects->commit_graph; for (i = 0; i < g->num_commits; i++) { - const unsigned char *hash = g->chunk_oid_lookup + g->hash_len * i; - hashcpy(ctx->oids.list[ctx->oids.nr++].hash, hash); + struct object_id oid; + hashcpy(oid.hash, g->chunk_oid_lookup + g->hash_len * i); + oid_array_append(&ctx->oids, &oid); } } @@ -2274,7 +2242,7 @@ int write_commit_graph(struct object_directory *odb, cleanup: free(ctx->graph_name); free(ctx->commits.list); - free(ctx->oids.list); + oid_array_clear(&ctx->oids); if (ctx->commit_graph_filenames_after) { for (i = 0; i < ctx->num_commit_graphs_after; i++) { From 3361390cbedc962adcddcfd98676695c125fa180 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Dec 2020 14:11:08 -0500 Subject: [PATCH 16/42] commit-graph: use size_t for array allocation and indexing Our packed_commit_list is an array of pointers to commit structs. We use "int" for the allocation, which is 32-bit even on 64-bit platforms. This isn't likely to overflow in practice (we're writing commit graphs, so you'd need to actually have billions of unique commits in the repository). But it's good practice to use size_t for allocations. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- commit-graph.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commit-graph.c b/commit-graph.c index 4a718fd6e6..06f8dc1d89 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -932,8 +932,8 @@ struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit struct packed_commit_list { struct commit **list; - int nr; - int alloc; + size_t nr; + size_t alloc; }; struct write_commit_graph_context { From 469f17d09789e781bee22edf6233f234a2c5afd3 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 7 Dec 2020 15:19:40 +0000 Subject: [PATCH 17/42] t7064: avoid relying on a specific default branch name To allow us to consider a change in the default behavior of `git init` where it uses a more inclusive name for the initial branch, we must first teach the test suite not to rely on a specific default branch name. In this patch, we teach t7064 that trick. To that end, we set a specific name for the initial branch. Ideally, we would simply start out by calling `git branch -M initial-branch`, but there is a bug in `git branch -M` that does not allow renaming branches unless they already have commits. This will be fixed in the `js/init-defaultbranch-advice` topic, and until that time, we use the equivalent (but less intuitive) `git checkout -f --orphan`. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t7064-wtstatus-pv2.sh | 103 ++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/t/t7064-wtstatus-pv2.sh b/t/t7064-wtstatus-pv2.sh index 537787e598..601b47830b 100755 --- a/t/t7064-wtstatus-pv2.sh +++ b/t/t7064-wtstatus-pv2.sh @@ -9,6 +9,7 @@ This test exercises porcelain V2 output for git status.' test_expect_success setup ' + git checkout -f --orphan initial-branch && test_tick && git config core.autocrlf false && echo x >file_x && @@ -22,7 +23,7 @@ test_expect_success setup ' test_expect_success 'before initial commit, nothing added, only untracked' ' cat >expect <<-EOF && # branch.oid (initial) - # branch.head master + # branch.head initial-branch ? actual ? dir1/ ? expect @@ -45,7 +46,7 @@ test_expect_success 'before initial commit, things added' ' cat >expect <<-EOF && # branch.oid (initial) - # branch.head master + # branch.head initial-branch 1 A. N... 000000 100644 100644 $ZERO_OID $OID_A dir1/file_a 1 A. N... 000000 100644 100644 $ZERO_OID $OID_B dir1/file_b 1 A. N... 000000 100644 100644 $ZERO_OID $OID_X file_x @@ -62,7 +63,7 @@ test_expect_success 'before initial commit, things added' ' test_expect_success 'before initial commit, things added (-z)' ' lf_to_nul >expect <<-EOF && # branch.oid (initial) - # branch.head master + # branch.head initial-branch 1 A. N... 000000 100644 100644 $ZERO_OID $OID_A dir1/file_a 1 A. N... 000000 100644 100644 $ZERO_OID $OID_B dir1/file_b 1 A. N... 000000 100644 100644 $ZERO_OID $OID_X file_x @@ -81,7 +82,7 @@ test_expect_success 'make first commit, comfirm HEAD oid and branch' ' H0=$(git rev-parse HEAD) && cat >expect <<-EOF && # branch.oid $H0 - # branch.head master + # branch.head initial-branch ? actual ? expect EOF @@ -98,7 +99,7 @@ test_expect_success 'after first commit, create unstaged changes' ' cat >expect <<-EOF && # branch.oid $H0 - # branch.head master + # branch.head initial-branch 1 .M N... 100644 100644 100644 $OID_X $OID_X file_x 1 .D N... 100644 100644 000000 $OID_Z $OID_Z file_z ? actual @@ -126,7 +127,7 @@ test_expect_success 'after first commit, stage existing changes' ' cat >expect <<-EOF && # branch.oid $H0 - # branch.head master + # branch.head initial-branch 1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x 1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z ? actual @@ -143,7 +144,7 @@ test_expect_success 'rename causes 2 path lines' ' q_to_tab >expect <<-EOF && # branch.oid $H0 - # branch.head master + # branch.head initial-branch 1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x 1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z 2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y @@ -161,7 +162,7 @@ test_expect_success 'rename causes 2 path lines (-z)' ' ## Lines use NUL path separator and line terminator, so double transform here. q_to_nul <<-EOF | lf_to_nul >expect && # branch.oid $H0 - # branch.head master + # branch.head initial-branch 1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x 1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z 2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y @@ -179,7 +180,7 @@ test_expect_success 'make second commit, confirm clean and new HEAD oid' ' cat >expect <<-EOF && # branch.oid $H1 - # branch.head master + # branch.head initial-branch ? actual ? expect EOF @@ -231,7 +232,7 @@ test_expect_success 'create and commit permanent ignore file' ' cat >expect <<-EOF && # branch.oid $H1 - # branch.head master + # branch.head initial-branch EOF git status --porcelain=v2 --branch >actual && @@ -257,14 +258,14 @@ test_expect_success 'verify --intent-to-add output' ' test_expect_success 'verify AA (add-add) conflict' ' test_when_finished "git reset --hard" && - git branch AA_A master && + git branch AA_A initial-branch && git checkout AA_A && echo "Branch AA_A" >conflict.txt && OID_AA_A=$(git hash-object -t blob -- conflict.txt) && git add conflict.txt && git commit -m "branch aa_a" && - git branch AA_B master && + git branch AA_B initial-branch && git checkout AA_B && echo "Branch AA_B" >conflict.txt && OID_AA_B=$(git hash-object -t blob -- conflict.txt) && @@ -290,7 +291,7 @@ test_expect_success 'verify AA (add-add) conflict' ' test_expect_success 'verify UU (edit-edit) conflict' ' test_when_finished "git reset --hard" && - git branch UU_ANC master && + git branch UU_ANC initial-branch && git checkout UU_ANC && echo "Ancestor" >conflict.txt && OID_UU_ANC=$(git hash-object -t blob -- conflict.txt) && @@ -328,18 +329,18 @@ test_expect_success 'verify UU (edit-edit) conflict' ' ' test_expect_success 'verify upstream fields in branch header' ' - git checkout master && + git checkout initial-branch && test_when_finished "rm -rf sub_repo" && git clone . sub_repo && ( - ## Confirm local master tracks remote master. + ## Confirm local initial-branch tracks remote initial-branch. cd sub_repo && HUF=$(git rev-parse HEAD) && cat >expect <<-EOF && # branch.oid $HUF - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +0 -0 EOF @@ -355,8 +356,8 @@ test_expect_success 'verify upstream fields in branch header' ' cat >expect <<-EOF && # branch.oid $HUF - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +1 -0 EOF @@ -367,9 +368,9 @@ test_expect_success 'verify upstream fields in branch header' ' git status --porcelain=v2 --untracked-files=all >actual && test_must_be_empty actual && - ## Test upstream-gone case. Fake this by pointing origin/master at - ## a non-existing commit. - OLD=$(git rev-parse origin/master) && + ## Test upstream-gone case. Fake this by pointing + ## origin/initial-branch at a non-existing commit. + OLD=$(git rev-parse origin/initial-branch) && NEW=$ZERO_OID && mv .git/packed-refs .git/old-packed-refs && sed "s/$OLD/$NEW/g" <.git/old-packed-refs >.git/packed-refs && @@ -378,8 +379,8 @@ test_expect_success 'verify upstream fields in branch header' ' cat >expect <<-EOF && # branch.oid $HUF - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch EOF git status --porcelain=v2 --branch --untracked-files=all >actual && @@ -388,19 +389,19 @@ test_expect_success 'verify upstream fields in branch header' ' ' test_expect_success 'verify --[no-]ahead-behind with V2 format' ' - git checkout master && + git checkout initial-branch && test_when_finished "rm -rf sub_repo" && git clone . sub_repo && ( - ## Confirm local master tracks remote master. + ## Confirm local initial-branch tracks remote initial-branch. cd sub_repo && HUF=$(git rev-parse HEAD) && # Confirm --no-ahead-behind reports traditional branch.ab with 0/0 for equal branches. cat >expect <<-EOF && # branch.oid $HUF - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +0 -0 EOF @@ -410,8 +411,8 @@ test_expect_success 'verify --[no-]ahead-behind with V2 format' ' # Confirm --ahead-behind reports traditional branch.ab with 0/0. cat >expect <<-EOF && # branch.oid $HUF - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +0 -0 EOF @@ -428,8 +429,8 @@ test_expect_success 'verify --[no-]ahead-behind with V2 format' ' # Confirm --no-ahead-behind reports branch.ab with ?/? for non-equal branches. cat >expect <<-EOF && # branch.oid $HUF - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +? -? EOF @@ -439,8 +440,8 @@ test_expect_success 'verify --[no-]ahead-behind with V2 format' ' # Confirm --ahead-behind reports traditional branch.ab with 1/0. cat >expect <<-EOF && # branch.oid $HUF - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +1 -0 EOF @@ -458,7 +459,7 @@ test_expect_success 'verify --[no-]ahead-behind with V2 format' ' ' test_expect_success 'create and add submodule, submodule appears clean (A. S...)' ' - git checkout master && + git checkout initial-branch && git clone . sub_repo && git clone . super_repo && ( cd super_repo && @@ -471,8 +472,8 @@ test_expect_success 'create and add submodule, submodule appears clean (A. S...) cat >expect <<-EOF && # branch.oid $HSUP - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +0 -0 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules 1 A. S... 000000 160000 160000 $ZERO_OID $HSUB sub1 @@ -496,8 +497,8 @@ test_expect_success 'untracked changes in added submodule (AM S..U)' ' cat >expect <<-EOF && # branch.oid $HSUP - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +0 -0 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules 1 AM S..U 000000 160000 160000 $ZERO_OID $HSUB sub1 @@ -521,8 +522,8 @@ test_expect_success 'staged changes in added submodule (AM S.M.)' ' cat >expect <<-EOF && # branch.oid $HSUP - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +0 -0 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules 1 AM S.M. 000000 160000 160000 $ZERO_OID $HSUB sub1 @@ -548,8 +549,8 @@ test_expect_success 'staged and unstaged changes in added (AM S.M.)' ' cat >expect <<-EOF && # branch.oid $HSUP - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +0 -0 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules 1 AM S.M. 000000 160000 160000 $ZERO_OID $HSUB sub1 @@ -575,8 +576,8 @@ test_expect_success 'staged and untracked changes in added submodule (AM S.MU)' cat >expect <<-EOF && # branch.oid $HSUP - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +0 -0 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules 1 AM S.MU 000000 160000 160000 $ZERO_OID $HSUB sub1 @@ -602,8 +603,8 @@ test_expect_success 'commit within the submodule appears as new commit in super cat >expect <<-EOF && # branch.oid $HSUP - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +0 -0 1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules 1 AM SC.. 000000 160000 160000 $ZERO_OID $HSUB sub1 @@ -625,8 +626,8 @@ test_expect_success 'stage submodule in super and commit' ' cat >expect <<-EOF && # branch.oid $HSUP - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +1 -0 EOF @@ -646,8 +647,8 @@ test_expect_success 'make unstaged changes in existing submodule (.M S.M.)' ' cat >expect <<-EOF && # branch.oid $HSUP - # branch.head master - # branch.upstream origin/master + # branch.head initial-branch + # branch.upstream origin/initial-branch # branch.ab +1 -0 1 .M S.M. 160000 160000 160000 $HSUB $HSUB sub1 EOF From 54df87555b12d96b76a2b63bf76067475881cc35 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Tue, 8 Dec 2020 22:31:44 +0000 Subject: [PATCH 18/42] Documentation/Makefile: conditionally include doc.dep The 'clean' target is noticeably slow on cygwin, even for a 'do-nothing' invocation of 'make clean'. For example, the second 'make clean' below: $ make clean >/dev/null 2>&1 $ make clean GIT_VERSION = 2.29.0 ... make[1]: Entering directory '/home/ramsay/git/Documentation' GEN mergetools-list.made GEN cmd-list.made GEN doc.dep ... $ has been timed at 23.339s, using git v2.29.0, on my laptop (an old core i5-4200M @ 2.50GHz, 8GB RAM, 1TB HDD). Notice that, since the 'doc.dep' file does not exist, make takes the time (about 8s) to generate several files in order to create the doc.dep include file. (If an 'include' file is missing, but a target for the said file is present in the Makefile, make will execute that target and, if that file now exists, throw away all its internal data and re-read and re-parse the Makefile). Having spent the time to include the 'doc.dep' file, the 'clean' target immediately deletes those files. The document dependencies specified in the 'doc.dep' include file, expressed as make targets and prerequisites, do not affect what the 'clean' target removes. Therefore, the time spent in generating the dependencies is completely wasted effort. In order to eliminate such wasted effort, use the value of the internal $(MAKECMDGOALS) variable to only '-include doc.dep' when the target is not 'clean'. (This drops the time down to 12.364s, on my laptop, giving an improvement of 47.02%). Signed-off-by: Ramsay Jones Signed-off-by: Junio C Hamano --- Documentation/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/Makefile b/Documentation/Makefile index 80d1908a44..652d57a1b6 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -286,7 +286,9 @@ doc.dep : $(docdep_prereqs) $(wildcard *.txt) $(wildcard config/*.txt) build-doc $(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \ mv $@+ $@ +ifneq ($(MAKECMDGOALS),clean) -include doc.dep +endif cmds_txt = cmds-ancillaryinterrogators.txt \ cmds-ancillarymanipulators.txt \ From 7a9272a836547d1b8e71e41e450027799fcfada0 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Tue, 8 Dec 2020 22:33:05 +0000 Subject: [PATCH 19/42] Documentation/Makefile: conditionally include ../GIT-VERSION-FILE The 'clean' target is still noticeably slow on cygwin, despite the substantial improvement made by the previous patch. For example, the second invocation of 'make clean' below: $ make clean >/dev/null 2>&1 $ make clean ... make[1]: Entering directory '/home/ramsay/git/Documentation' make[2]: Entering directory '/home/ramsay/git' make[2]: 'GIT-VERSION-FILE' is up to date. make[2]: Leaving directory '/home/ramsay/git' ... $ has been timed at 12.364s on my laptop (an old core i5-4200M @ 2.50GHz, 8GB RAM, 1TB HDD). Notice that the 'clean' target is making a nested call to the parent Makefile to ensure that the GIT-VERSION-FILE is up-to-date (prior to the previous patch, there would have been _two_ such invocations). This is to ensure that the $(GIT_VERSION) make variable is set, once that file had been included. However, the 'clean' target does not use the $(GIT_VERSION) variable, directly or indirectly, so it does not have any affect on what the target removes. Therefore, the time spent on ensuring an up to date GIT-VERSION-FILE is wasted effort. In order to eliminate such wasted effort, use the value of the internal $(MAKECMDGOALS) variable to only '-include ../GIT-VERSION-FILE' when the target is not 'clean'. (This drops the time down to 10.361s, on my laptop, giving an improvement of 16.20%). Signed-off-by: Ramsay Jones Signed-off-by: Junio C Hamano --- Documentation/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/Makefile b/Documentation/Makefile index 652d57a1b6..5c680024eb 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -272,7 +272,9 @@ install-html: html ../GIT-VERSION-FILE: FORCE $(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) GIT-VERSION-FILE +ifneq ($(MAKECMDGOALS),clean) -include ../GIT-VERSION-FILE +endif # # Determine "include::" file references in asciidoc files. From e3a9237e8433351b8f9a45fa749b6aad3ce5164b Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Tue, 8 Dec 2020 22:34:28 +0000 Subject: [PATCH 20/42] gitweb/Makefile: conditionally include ../GIT-VERSION-FILE The 'clean' target is still noticeably slow on cygwin, despite the improvements made by previous patches. For example, the second invocation of 'make clean' below: $ make clean >/dev/null 2>&1 $ make clean ... make[1]: Entering directory '/home/ramsay/git/gitweb' make[2]: Entering directory '/home/ramsay/git' make[2]: 'GIT-VERSION-FILE' is up to date. make[2]: Leaving directory '/home/ramsay/git' ... $ has been timed at 10.361s on my laptop (an old core i5-4200M @ 2.50GHz, 8GB RAM, 1TB HDD). Notice that the 'clean' target is making a nested call to the parent Makefile to ensure that the GIT-VERSION-FILE is up-to-date. This is to ensure that the $(GIT_VERSION) make variable is set, once that file had been included. However, the 'clean' target does not use the $(GIT_VERSION) variable, directly or indirectly, so it does not have any affect on what the target removes. Therefore, the time spent on ensuring an up to date GIT-VERSION-FILE is wasted effort. In order to eliminate such wasted effort, use the value of the internal $(MAKECMDGOALS) variable to only '-include ../GIT-VERSION-FILE' when the target is not 'clean'. (This drops the time down to 8.430s, on my laptop, giving an improvement of 18.64%). Signed-off-by: Ramsay Jones Signed-off-by: Junio C Hamano --- gitweb/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gitweb/Makefile b/gitweb/Makefile index cd194d057f..f13e23c4de 100644 --- a/gitweb/Makefile +++ b/gitweb/Makefile @@ -48,7 +48,9 @@ HIGHLIGHT_BIN = highlight ../GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE $(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) GIT-VERSION-FILE +ifneq ($(MAKECMDGOALS),clean) -include ../GIT-VERSION-FILE +endif ### Build rules From 98836a8a127c6d6f31d5976a757b33ae4ca048e9 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Tue, 8 Dec 2020 22:35:27 +0000 Subject: [PATCH 21/42] Makefile: don't try to clean old debian build product The 'clean' target includes code to remove an '*.tar.gz' file that was the by-product of a debian build. This was originally added by commit 5a571cdd8a (Clean generated files a bit more, to cope with Debian build droppings., 2005-08-12). However, all support for the 'debian build' was dropped by commit 7d0e65b892 (Retire debian/ directory., 2006-01-06), which seems to have simply forgotten to remove the 'git-core_$(GIT_VERSION)-*.tar.gz' from the 'clean' target. Remove it now. Signed-off-by: Ramsay Jones Signed-off-by: Junio C Hamano --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 45bce31016..96e738924c 100644 --- a/Makefile +++ b/Makefile @@ -3159,7 +3159,7 @@ clean: profile-clean coverage-clean cocciclean $(RM) -r po/build/ $(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope* $(RM) -r $(GIT_TARNAME) .doc-tmp-dir - $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz + $(RM) $(GIT_TARNAME).tar.gz $(RM) $(htmldocs).tar.gz $(manpages).tar.gz $(MAKE) -C Documentation/ clean $(RM) Documentation/GIT-EXCLUDED-PROGRAMS From c5312033dd81771def2268d57f64e5551d9e11bf Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Tue, 8 Dec 2020 22:36:33 +0000 Subject: [PATCH 22/42] Makefile: don't use a versioned temp distribution directory The 'dist' target uses a versioned temp directory, $(GIT_TARNAME), into which it copies various files added to the distribution tarball. Should it be necessary to remove this directory in the 'clean' target, since the name depends on $(GIT_VERSION), the current HEAD must be positioned on the same commit as when 'make dist' was issued. Otherwise, the target will fail to remove that directory. Create an '.dist-tmp-dir' directory and copy the various files into this now un-versioned directory while creating the distribution tarball. Change the 'clean' target to remove the '.dist-tmp-dir' directory, instead of the version dependent $(GIT_TARNAME) directory. Signed-off-by: Ramsay Jones Signed-off-by: Junio C Hamano --- Makefile | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 96e738924c..2060f3787c 100644 --- a/Makefile +++ b/Makefile @@ -3061,9 +3061,9 @@ GIT_TARNAME = git-$(GIT_VERSION) GIT_ARCHIVE_EXTRA_FILES = \ --prefix=$(GIT_TARNAME)/ \ --add-file=configure \ - --add-file=$(GIT_TARNAME)/version \ + --add-file=.dist-tmp-dir/version \ --prefix=$(GIT_TARNAME)/git-gui/ \ - --add-file=$(GIT_TARNAME)/git-gui/version + --add-file=.dist-tmp-dir/git-gui/version ifdef DC_SHA1_SUBMODULE GIT_ARCHIVE_EXTRA_FILES += \ --prefix=$(GIT_TARNAME)/sha1collisiondetection/ \ @@ -3075,13 +3075,14 @@ GIT_ARCHIVE_EXTRA_FILES += \ --add-file=sha1collisiondetection/lib/ubc_check.h endif dist: git-archive$(X) configure - @mkdir -p $(GIT_TARNAME) - @echo $(GIT_VERSION) > $(GIT_TARNAME)/version - @$(MAKE) -C git-gui TARDIR=../$(GIT_TARNAME)/git-gui dist-version + @$(RM) -r .dist-tmp-dir + @mkdir .dist-tmp-dir + @echo $(GIT_VERSION) > .dist-tmp-dir/version + @$(MAKE) -C git-gui TARDIR=../.dist-tmp-dir/git-gui dist-version ./git-archive --format=tar \ $(GIT_ARCHIVE_EXTRA_FILES) \ --prefix=$(GIT_TARNAME)/ HEAD^{tree} > $(GIT_TARNAME).tar - @$(RM) -r $(GIT_TARNAME) + @$(RM) -r .dist-tmp-dir gzip -f -9 $(GIT_TARNAME).tar rpm:: @@ -3158,7 +3159,7 @@ clean: profile-clean coverage-clean cocciclean $(RM) -r bin-wrappers $(dep_dirs) $(compdb_dir) compile_commands.json $(RM) -r po/build/ $(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope* - $(RM) -r $(GIT_TARNAME) .doc-tmp-dir + $(RM) -r .dist-tmp-dir .doc-tmp-dir $(RM) $(GIT_TARNAME).tar.gz $(RM) $(htmldocs).tar.gz $(manpages).tar.gz $(MAKE) -C Documentation/ clean From 610a3fc9536d7016fd850d622f41bf884c290062 Mon Sep 17 00:00:00 2001 From: Josh Steadmon Date: Wed, 9 Dec 2020 11:16:16 -0800 Subject: [PATCH 23/42] t7900: use --fixed-value in git-maintenance tests Use --fixed-value in git-config calls in the git-maintenance tests, so that the tests will continue to work even if the repo path contains regexp metacharacters. Signed-off-by: Josh Steadmon Signed-off-by: Junio C Hamano --- t/t7900-maintenance.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index ee91a714b9..e4fcee8686 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -420,7 +420,7 @@ test_expect_success 'start from empty cron table' ' GIT_TEST_CRONTAB="test-tool crontab cron.txt" git maintenance start && # start registers the repo - git config --get --global maintenance.repo "$(pwd)" && + git config --get --global --fixed-value maintenance.repo "$(pwd)" && grep "for-each-repo --config=maintenance.repo maintenance run --schedule=daily" cron.txt && grep "for-each-repo --config=maintenance.repo maintenance run --schedule=hourly" cron.txt && @@ -431,7 +431,7 @@ test_expect_success 'stop from existing schedule' ' GIT_TEST_CRONTAB="test-tool crontab cron.txt" git maintenance stop && # stop does not unregister the repo - git config --get --global maintenance.repo "$(pwd)" && + git config --get --global --fixed-value maintenance.repo "$(pwd)" && # Operation is idempotent GIT_TEST_CRONTAB="test-tool crontab cron.txt" git maintenance stop && From 1296cbe4b4675f429eb20b85bb86ec61546103fb Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 11 Dec 2020 11:36:54 +0000 Subject: [PATCH 24/42] init: document `init.defaultBranch` better Our documentation does not mention any future plan to change 'master' to other value. It is a good idea to document this, though. Initial-patch-by: Junio C Hamano Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-init.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 59ecda6c17..b611d80697 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -20,8 +20,9 @@ DESCRIPTION This command creates an empty Git repository - basically a `.git` directory with subdirectories for `objects`, `refs/heads`, -`refs/tags`, and template files. An initial `HEAD` file that -references the HEAD of the master branch is also created. +`refs/tags`, and template files. An initial branch without any +commits will be created (see the `--initial-branch` option below +for its name). If the `$GIT_DIR` environment variable is set then it specifies a path to use instead of `./.git` for the base of the repository. @@ -73,8 +74,10 @@ If this is reinitialization, the repository will be moved to the specified path. -b :: --initial-branch=:: -Use the specified name for the initial branch in the newly created repository. -If not specified, fall back to the default name: `master`. +Use the specified name for the initial branch in the newly created +repository. If not specified, fall back to the default name (currently +`master`, but this is subject to change in the future; the name can be +customized via the `init.defaultBranch` configuration variable). --shared[=(false|true|umask|group|all|world|everybody|0xxx)]:: From cfaff3aac8063ec72f03c6761328c7fa44a15b34 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 11 Dec 2020 11:36:55 +0000 Subject: [PATCH 25/42] branch -m: allow renaming a yet-unborn branch In one of the next commits, we would like to give users some advice regarding the initial branch name, and how to modify it. To that end, it would be good if `git branch -m ` worked in a freshly initialized repository without any commits. Let's make it so. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin/branch.c | 4 +++- t/t0001-init.sh | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/builtin/branch.c b/builtin/branch.c index efb30b8820..200da319f1 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -538,7 +538,9 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int strbuf_addf(&logmsg, "Branch: renamed %s to %s", oldref.buf, newref.buf); - if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf)) + if (!copy && + (!head || strcmp(oldname, head) || !is_null_oid(&head_oid)) && + rename_ref(oldref.buf, newref.buf, logmsg.buf)) die(_("Branch rename failed")); if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf)) die(_("Branch copy failed")); diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 69a320489f..bb23e56a16 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -571,4 +571,12 @@ test_expect_success 'invalid default branch name' ' test_i18ngrep "invalid branch name" err ' +test_expect_success 'branch -m with the initial branch' ' + git init rename-initial && + git -C rename-initial branch -m renamed && + test renamed = $(git -C rename-initial symbolic-ref --short HEAD) && + git -C rename-initial branch -m renamed again && + test again = $(git -C rename-initial symbolic-ref --short HEAD) +' + test_done From cc0f13c57dedaf62c9f852b6bf363aee7e3392f1 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 11 Dec 2020 11:36:56 +0000 Subject: [PATCH 26/42] get_default_branch_name(): prepare for showing some advice We are about to introduce a message giving users running `git init` some advice about `init.defaultBranch`. This will necessarily be done in `repo_default_branch_name()`. Not all code paths want to show that advice, though. In particular, the `git clone` codepath _specifically_ asks for `init_db()` to be quiet, via the `INIT_DB_QUIET` flag. In preparation for showing users above-mentioned advice, let's change the function signature of `get_default_branch_name()` to accept the parameter `quiet`. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin/clone.c | 2 +- builtin/init-db.c | 8 +++++--- refs.c | 6 +++--- refs.h | 4 ++-- remote.c | 5 +++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index a0841923cf..64b1784011 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1323,7 +1323,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) remote_head = NULL; option_no_checkout = 1; if (!option_bare) { - const char *branch = git_default_branch_name(); + const char *branch = git_default_branch_name(0); char *ref = xstrfmt("refs/heads/%s", branch); install_branch_config(0, branch, remote_name, ref); diff --git a/builtin/init-db.c b/builtin/init-db.c index 01bc648d41..dcc45bef51 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -202,7 +202,8 @@ void initialize_repository_version(int hash_algo, int reinit) static int create_default_files(const char *template_path, const char *original_git_dir, const char *initial_branch, - const struct repository_format *fmt) + const struct repository_format *fmt, + int quiet) { struct stat st1; struct strbuf buf = STRBUF_INIT; @@ -267,7 +268,7 @@ static int create_default_files(const char *template_path, char *ref; if (!initial_branch) - initial_branch = git_default_branch_name(); + initial_branch = git_default_branch_name(quiet); ref = xstrfmt("refs/heads/%s", initial_branch); if (check_refname_format(ref, 0) < 0) @@ -438,7 +439,8 @@ int init_db(const char *git_dir, const char *real_git_dir, validate_hash_algorithm(&repo_fmt, hash); reinit = create_default_files(template_dir, original_git_dir, - initial_branch, &repo_fmt); + initial_branch, &repo_fmt, + flags & INIT_DB_QUIET); if (reinit && initial_branch) warning(_("re-init: ignored --initial-branch=%s"), initial_branch); diff --git a/refs.c b/refs.c index 392f0bbf68..8df03122d6 100644 --- a/refs.c +++ b/refs.c @@ -562,7 +562,7 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix) strvec_pushf(prefixes, *p, len, prefix); } -char *repo_default_branch_name(struct repository *r) +char *repo_default_branch_name(struct repository *r, int quiet) { const char *config_key = "init.defaultbranch"; const char *config_display_key = "init.defaultBranch"; @@ -585,12 +585,12 @@ char *repo_default_branch_name(struct repository *r) return ret; } -const char *git_default_branch_name(void) +const char *git_default_branch_name(int quiet) { static char *ret; if (!ret) - ret = repo_default_branch_name(the_repository); + ret = repo_default_branch_name(the_repository, quiet); return ret; } diff --git a/refs.h b/refs.h index 6695518156..ff05d2e9fe 100644 --- a/refs.h +++ b/refs.h @@ -170,8 +170,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref); * The return value of `repo_default_branch_name()` is an allocated string. The * return value of `git_default_branch_name()` is a singleton. */ -const char *git_default_branch_name(void); -char *repo_default_branch_name(struct repository *r); +const char *git_default_branch_name(int quiet); +char *repo_default_branch_name(struct repository *r, int quiet); /* * A ref_transaction represents a collection of reference updates that diff --git a/remote.c b/remote.c index 8a6dbbb903..bdb88d4b7d 100644 --- a/remote.c +++ b/remote.c @@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote) if (frag) *(frag++) = '\0'; else - frag = (char *)git_default_branch_name(); + frag = (char *)git_default_branch_name(0); add_url_alias(remote, strbuf_detach(&buf, NULL)); refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s", @@ -2206,7 +2206,8 @@ struct ref *guess_remote_head(const struct ref *head, /* If a remote branch exists with the default branch name, let's use it. */ if (!all) { - char *ref = xstrfmt("refs/heads/%s", git_default_branch_name()); + char *ref = xstrfmt("refs/heads/%s", + git_default_branch_name(0)); r = find_ref_by_name(refs, ref); free(ref); From 675704c74dd4476f455bfa91e72eb9e163317c10 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 11 Dec 2020 11:36:57 +0000 Subject: [PATCH 27/42] init: provide useful advice about init.defaultBranch To give ample warning for users wishing to override Git's the fall-back for an unconfigured `init.defaultBranch` (in case we decide to change it in a future Git version), let's introduce some advice that is shown upon `git init` when that value is not set. Note: two test cases in Git's test suite want to verify that the `stderr` output of `git init` is empty. It is now necessary to suppress the advice, we now do that via the `init.defaultBranch` setting. While not strictly necessary, we also set this to `false` in `test_create_repo()`. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- refs.c | 18 +++++++++++++++++- t/t0001-init.sh | 9 ++++++++- t/t1510-repo-setup.sh | 2 +- t/test-lib-functions.sh | 4 +++- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/refs.c b/refs.c index 8df03122d6..13dc2c3291 100644 --- a/refs.c +++ b/refs.c @@ -562,6 +562,19 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix) strvec_pushf(prefixes, *p, len, prefix); } +static const char default_branch_name_advice[] = N_( +"Using '%s' as the name for the initial branch. This default branch name\n" +"is subject to change. To configure the initial branch name to use in all\n" +"of your new repositories, which will suppress this warning, call:\n" +"\n" +"\tgit config --global init.defaultBranch \n" +"\n" +"Names commonly chosen instead of 'master' are 'main', 'trunk' and\n" +"'development'. The just-created branch can be renamed via this command:\n" +"\n" +"\tgit branch -m \n" +); + char *repo_default_branch_name(struct repository *r, int quiet) { const char *config_key = "init.defaultbranch"; @@ -574,8 +587,11 @@ char *repo_default_branch_name(struct repository *r, int quiet) else if (repo_config_get_string(r, config_key, &ret) < 0) die(_("could not retrieve `%s`"), config_display_key); - if (!ret) + if (!ret) { ret = xstrdup("master"); + if (!quiet) + advise(_(default_branch_name_advice), ret); + } full_ref = xstrfmt("refs/heads/%s", ret); if (check_refname_format(full_ref, 0)) diff --git a/t/t0001-init.sh b/t/t0001-init.sh index bb23e56a16..0803994874 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -163,7 +163,7 @@ test_expect_success 'reinit' ' ( mkdir again && cd again && - git init >out1 2>err1 && + git -c init.defaultBranch=initial init >out1 2>err1 && git init >out2 2>err2 ) && test_i18ngrep "Initialized empty" again/out1 && @@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' ' grep nmb actual ' +test_expect_success 'advice on unconfigured init.defaultBranch' ' + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \ + init unconfigured-default-branch-name 2>err && + test_decode_color decoded && + test_i18ngrep "hint: " decoded +' + test_expect_success 'overridden default main branch name (env)' ' test_config_global init.defaultBranch nmb && GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env && diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh index 9974457f56..bbfe05b8e4 100755 --- a/t/t1510-repo-setup.sh +++ b/t/t1510-repo-setup.sh @@ -79,7 +79,7 @@ setup_repo () { name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 && sane_unset GIT_DIR GIT_WORK_TREE && - git init "$name" && + git -c init.defaultBranch=initial init "$name" && maybe_config "$name/.git/config" core.worktree "$worktreecfg" && maybe_config "$name/.git/config" core.bare "$barecfg" && mkdir -p "$name/sub/sub" && diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 59bbf75e83..9910102ae1 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -1202,7 +1202,9 @@ test_create_repo () { mkdir -p "$repo" ( cd "$repo" || error "Cannot setup test environment" - "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \ + "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" -c \ + init.defaultBranch="${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}" \ + init \ "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 || error "cannot run git init -- have you built things yet?" mv .git/hooks .git/hooks-disabled From 633eebe142d7c9ab3a06e745c48e41af58d99b71 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 13 Dec 2020 11:13:40 +0100 Subject: [PATCH 28/42] docs: multi-pack-index: remove note about future 'verify' work This was implemented in the 'git multi-pack-index' command and merged in 468b3221 (Merge branch 'ds/multi-pack-verify', 2018-10-10). And there's no 'git midx' command. Signed-off-by: Johannes Berg Reviewed-by: Derrick Stolee Signed-off-by: Junio C Hamano --- Documentation/technical/multi-pack-index.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Documentation/technical/multi-pack-index.txt b/Documentation/technical/multi-pack-index.txt index d7e57639f7..2aa0c48e17 100644 --- a/Documentation/technical/multi-pack-index.txt +++ b/Documentation/technical/multi-pack-index.txt @@ -60,10 +60,6 @@ Design Details Future Work ----------- -- Add a 'verify' subcommand to the 'git midx' builtin to verify the - contents of the multi-pack-index file match the offsets listed in - the corresponding pack-indexes. - - The multi-pack-index allows many packfiles, especially in a context where repacking is expensive (such as a very large repo), or unexpected maintenance time is unacceptable (such as a high-demand From 5885367e8f4d9fa2637642bb2eb1db8542ffd551 Mon Sep 17 00:00:00 2001 From: Jeff Hostetler Date: Mon, 14 Dec 2020 13:33:42 +0000 Subject: [PATCH 29/42] index-format.txt: document v2 format of file system monitor extension Update the documentation of the file system monitor extension to describe version 2. The format was extended to support opaque tokens in: 56c6910028 fsmonitor: change last update timestamp on the index_state to opaque token Signed-off-by: Jeff Hostetler Signed-off-by: Junio C Hamano --- Documentation/technical/index-format.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/technical/index-format.txt b/Documentation/technical/index-format.txt index faa25c5c52..3a433a2090 100644 --- a/Documentation/technical/index-format.txt +++ b/Documentation/technical/index-format.txt @@ -304,12 +304,18 @@ The remaining data of each directory block is grouped by type: The extension starts with - - 32-bit version number: the current supported version is 1. + - 32-bit version number: the current supported versions are 1 and 2. - - 64-bit time: the extension data reflects all changes through the given + - (Version 1) + 64-bit time: the extension data reflects all changes through the given time which is stored as the nanoseconds elapsed since midnight, January 1, 1970. + - (Version 2) + A null terminated string: an opaque token defined by the file system + monitor application. The extension data reflects all changes relative + to that token. + - 32-bit bitmap size: the size of the CE_FSMONITOR_VALID bitmap. - An ewah bitmap, the n-th bit indicates whether the n-th index entry From fcedbc1cf60402905f2a1bac4c7c27fb7125871a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?= Date: Thu, 10 Dec 2020 21:30:17 +0700 Subject: [PATCH 30/42] doc: mention Python 3.x supports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 0b4396f068, (git-p4: make python2.7 the oldest supported version, 2019-12-13) pointed out that git-p4 uses Python 2.7-or-later features in the code. In addition, git-p4 gained enough support for Python 3 from 6cec21a82f, (git-p4: encode/decode communication with p4 for python3, 2019-12-13). Let's update our documentation to reflect that fact. Signed-off-by: Đoàn Trần Công Danh Signed-off-by: Junio C Hamano --- INSTALL | 3 +-- Makefile | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/INSTALL b/INSTALL index 9ba33e6a14..8474ad01bf 100644 --- a/INSTALL +++ b/INSTALL @@ -165,8 +165,7 @@ Issues of note: use English. Under autoconf the configure script will do this automatically if it can't find libintl on the system. - - Python version 2.4 or later (but not 3.x, which is not - supported by Perforce) is needed to use the git-p4 interface + - Python version 2.7 or later is needed to use the git-p4 interface to Perforce. - Some platform specific issues are dealt with Makefile rules, diff --git a/Makefile b/Makefile index 6fb86c5862..a751065b24 100644 --- a/Makefile +++ b/Makefile @@ -303,7 +303,7 @@ all:: # modules, instead of the fallbacks shipped with Git. # # Define PYTHON_PATH to the path of your Python binary (often /usr/bin/python -# but /usr/bin/python2.7 on some platforms). +# but /usr/bin/python2.7 or /usr/bin/python3 on some platforms). # # Define NO_PYTHON if you do not want Python scripts or libraries at all. # From 37e73233c34ceac9f16bd8e7c33ae4c8a4157b1c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Dec 2020 13:25:36 -0800 Subject: [PATCH 31/42] strmap: make callers of strmap_remove() to call it in void context Two "static inline" functions, both of which return void, call strmap_remove() and tries to return the value it returns as their return value, which is just bogus, as strmap_remove() returns void itself. Call it in the void context and fall-thru the control to the end instead. Reported-by: Randall S. Becker Signed-off-by: Junio C Hamano --- strmap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/strmap.h b/strmap.h index c4c104411b..1e152d832d 100644 --- a/strmap.h +++ b/strmap.h @@ -165,7 +165,7 @@ static inline int strintmap_contains(struct strintmap *map, const char *str) static inline void strintmap_remove(struct strintmap *map, const char *str) { - return strmap_remove(&map->map, str, 0); + strmap_remove(&map->map, str, 0); } static inline int strintmap_empty(struct strintmap *map) @@ -249,7 +249,7 @@ static inline int strset_contains(struct strset *set, const char *str) static inline void strset_remove(struct strset *set, const char *str) { - return strmap_remove(&set->map, str, 0); + strmap_remove(&set->map, str, 0); } static inline int strset_empty(struct strset *set) From 14639a47799461fbdb3bed6845c61a0ca0524200 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Dec 2020 13:26:17 -0800 Subject: [PATCH 32/42] compat-util: pretend that stub setitimer() always succeeds When 15b52a44 (compat-util: type-check parameters of no-op replacement functions, 2020-08-06) turned a handful of no-op C-preprocessor macros into static inline functions to give the callers a better type checking for their parameters, it forgot to return anything from the stubbed out setitimer() function, even though the function was defined to return an int just like the real thing. Since the original C-preprocessor macro implementation was to just turn the call to the function an empty statement, we know that the existing callers do not check the return value from it, and it does not matter what value we return. But it is safer to pretend that the call succeeded by returning 0 than making it fail by returning -1 and clobbering errno with some value. Reported-by: Randall S. Becker Signed-off-by: Junio C Hamano --- git-compat-util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-compat-util.h b/git-compat-util.h index 7a0fb7a045..421c90b5d8 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -273,7 +273,7 @@ struct itimerval { #ifdef NO_SETITIMER static inline int setitimer(int which, const struct itimerval *value, struct itimerval *newvalue) { - ; /* nothing */ + return 0; /* pretend success */ } #endif From 56f56ac50b932310c629832fad256e624ca451e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Wed, 16 Dec 2020 00:50:27 +0100 Subject: [PATCH 33/42] style: do not "break" in switch() after "return" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove this unreachable code. It was found by SunCC, it's found by a non-fatal warning emitted by SunCC. It's one of the things it's more vehement about than GCC & Clang. It complains about a lot of other similarly unreachable code, e.g. a BUG(...) without a "return", and a "return 0" after a long if/else, both of whom have "return" statements. Those are also genuine redundancies to a compiler, but arguably make the code a bit easier to read & less fragile to maintain. These return/break cases are just unnecessary however, and as seen here the surrounding code just did a plain "return" without a "break" already. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- apply.c | 2 -- builtin/fast-export.c | 1 - 2 files changed, 3 deletions(-) diff --git a/apply.c b/apply.c index 76dba93c97..66cf94393e 100644 --- a/apply.c +++ b/apply.c @@ -3948,10 +3948,8 @@ static int check_patch(struct apply_state *state, struct patch *patch) break; /* happy */ case EXISTS_IN_INDEX: return error(_("%s: already exists in index"), new_name); - break; case EXISTS_IN_INDEX_AS_ITA: return error(_("%s: does not match index"), new_name); - break; case EXISTS_IN_WORKTREE: return error(_("%s: already exists in working directory"), new_name); diff --git a/builtin/fast-export.c b/builtin/fast-export.c index d2e33f5005..0a60356b06 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -923,7 +923,6 @@ static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name) if (!tag) die("Tag %s points nowhere?", e->name); return (struct commit *)tag; - break; } default: return NULL; From f4698738f9dbe733e64f968fff95a9a4f881431e Mon Sep 17 00:00:00 2001 From: Eric Sunshine Date: Wed, 16 Dec 2020 02:39:07 -0500 Subject: [PATCH 34/42] t/perf: fix test_export() failure with BSD `sed` test_perf() runs each test in its own subshell which makes it difficult to persist variables between tests. test_export() addresses this shortcoming by grabbing the values of specified variables after a test runs but before the subshell exits, and writes those values to a file which is loaded into the environment of subsequent tests. To grab the values to be persisted, test_export() pipes the output of the shell's builtin `set` command through `sed` which plucks them out using a regular expression along the lines of `s/^(var1|var2)/.../p`. Unfortunately, though, this use of alternation is not portable. For instance, BSD-lineage `sed` (including macOS `sed`) does not support it in the default "basic regular expression" mode (BRE). It may be possible to enable "extended regular expression" mode (ERE) in some cases with `sed -E`, however, `-E` is neither portable nor part of POSIX. Fortunately, alternation is unnecessary in this case and can easily be avoided, so replace it with a series of simple expressions such as `s/^var1/.../p;s/^var2/.../p`. While at it, tighten the expressions so they match the variable names exactly rather than matching prefixes (i.e. use `s/^var1=/.../p`). If the requirements of test_export() become more complex in the future, then an alternative would be to replace `sed` with `perl` which supports alternation on all platforms, however, the simple elimination of alternation via multiple `sed` expressions suffices for the present. Reported-by: Sangeeta Diagnosed-by: Philippe Blain Signed-off-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/perf/perf-lib.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index 821581a885..22d727cef8 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -148,13 +148,18 @@ test_run_perf_ () { . '"$TEST_DIRECTORY"/test-lib-functions.sh' test_export () { [ $# != 0 ] || return 0 - test_export_="$test_export_\\|$1" + test_export_="$test_export_ $1" shift test_export "$@" } '"$1"' ret=$? -set | sed -n "s'"/'/'\\\\''/g"';s/^\\($test_export_\\)/export '"'&'"'/p" >test_vars +needles= +for v in $test_export_ +do + needles="$needles;s/^$v=/export $v=/p" +done +set | sed -n "s'"/'/'\\\\''/g"'$needles" >test_vars exit $ret' >&3 2>&4 eval_ret=$? From 50f04394908fe308a421b360951b1f73b00363ee Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 16 Dec 2020 17:27:13 -0800 Subject: [PATCH 35/42] diff: correct interaction between --exit-code and -I Just like "git diff -w --exit-code" should exit with 0 when ignoring whitespace differences results in no changes shown, if ignoring certain changes with "git diff -I --exit-code" result in an empty patch, we should exit with 0. The test suite did not cover the interaction between "--exit-code" and "-w"; add one while adding a new test for "--exit-code" + "-I". Signed-off-by: Junio C Hamano --- diff.c | 3 ++- t/t4015-diff-whitespace.sh | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/diff.c b/diff.c index 92e247fb83..e162d59eae 100644 --- a/diff.c +++ b/diff.c @@ -4602,7 +4602,8 @@ void diff_setup_done(struct diff_options *options) * inside contents. */ - if ((options->xdl_opts & XDF_WHITESPACE_FLAGS)) + if ((options->xdl_opts & XDF_WHITESPACE_FLAGS) || + options->ignore_regex_nr) options->flags.diff_from_contents = 1; else options->flags.diff_from_contents = 0; diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 88d3026894..8ae02fe3c3 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -567,6 +567,30 @@ test_expect_success '--check and --quiet are not exclusive' ' git diff --check --quiet ' +test_expect_success '-w and --exit-code interact sensibly' ' + test_when_finished "git checkout x" && + { + test_seq 15 && + echo " 16" + } >x && + test_must_fail git diff --exit-code && + git diff -w >actual && + test_must_be_empty actual && + git diff -w --exit-code +' + +test_expect_success '-I and --exit-code interact sensibly' ' + test_when_finished "git checkout x" && + { + test_seq 15 && + echo " 16" + } >x && + test_must_fail git diff --exit-code && + git diff -I. >actual && + test_must_be_empty actual && + git diff -I. --exit-code +' + test_expect_success 'check staged with no whitespace errors' ' echo "foo();" >x && git add x && From 731d578b4fe55fd2dbe7dfc5aa91aadfbce9a2b4 Mon Sep 17 00:00:00 2001 From: "Randall S. Becker" Date: Wed, 16 Dec 2020 17:07:52 -0500 Subject: [PATCH 36/42] config.mak.uname: remove old NonStop compatibility settings The MKDIR_WO_TRAILING_SLASH and NO_SETITIMER options are no longer needed on the NonStop platforms as both are now supported by the oldest supported operating system revision. Signed-off-by: Randall S. Becker Signed-off-by: Junio C Hamano --- config.mak.uname | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config.mak.uname b/config.mak.uname index c7eba69e54..ca627c56da 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -579,10 +579,6 @@ ifeq ($(uname_S),NONSTOP_KERNEL) NO_MMAP = YesPlease NO_POLL = YesPlease NO_INTPTR_T = UnfortunatelyYes - # Bug report 10-120822-4477 submitted to HP NonStop development. - MKDIR_WO_TRAILING_SLASH = YesPlease - # RFE 10-120912-4693 submitted to HP NonStop development. - NO_SETITIMER = UnfortunatelyYes SANE_TOOL_PATH = /usr/coreutils/bin:/usr/local/bin SHELL_PATH = /usr/coreutils/bin/bash endif From f9481b195b867dbdeead70d988e2e00d438d6f52 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 22 Nov 2020 20:45:37 +0100 Subject: [PATCH 37/42] git-gui: fix colored label backgrounds when using themed widgets The aqua theme on Mac doesn't support changing the background color for labels and frames [1]. Since the red, green, and yellow backgrounds of the labels for unstaged and staged files and the diff pane are so important design elements of git gui's main window, it's not acceptable for them to have grey backgrounds on Mac. To work around this, simply use non-themed widgets for all labels on Mac. This is not a big problem because labels don't look extremely different between the themed and non-themed versions. There are subtle differences, but they are not as bad as having the wrong background color. [1] https://stackoverflow.com/a/6723911 Signed-off-by: Stefan Haller Signed-off-by: Pratyush Yadav --- lib/themed.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/themed.tcl b/lib/themed.tcl index 83e3ac795f..02aae90144 100644 --- a/lib/themed.tcl +++ b/lib/themed.tcl @@ -174,7 +174,7 @@ proc InitEntryFrame {} { proc gold_frame {w args} { global use_ttk - if {$use_ttk} { + if {$use_ttk && ![is_MacOSX]} { eval [linsert $args 0 ttk::frame $w -style Gold.TFrame] } else { eval [linsert $args 0 frame $w -background gold] @@ -183,7 +183,7 @@ proc gold_frame {w args} { proc tlabel {w args} { global use_ttk - if {$use_ttk} { + if {$use_ttk && ![is_MacOSX]} { set cmd [list ttk::label $w -style Color.TLabel] foreach {k v} $args { switch -glob -- $k { From 5bc8b5d5c11bc01eac84e98657d9cfc0541ae6a3 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Mon, 7 Dec 2020 00:39:30 +0000 Subject: [PATCH 38/42] Makefile: conditionally include GIT-VERSION-FILE The 'clean' target is noticeably slow on cygwin, even for a 'do-nothing' invocation of 'make clean'. For example, the second 'make clean' given below: $ make clean >/dev/null 2>&1 $ make clean GITGUI_VERSION = 0.21.0.85.g3e5c rm -rf git-gui lib/tclIndex po/*.msg rm -rf GIT-VERSION-FILE GIT-GUI-VARS $ has been timed at 1.934s on my laptop (an old core i5-4200M @ 2.50GHz, 8GB RAM, 1TB HDD). Notice that the Makefile, as part of processing the 'clean' target, is updating the 'GIT-VERSION-FILE' file. This is to ensure that the $(GITGUI_VERSION) make variable is set, once that file had been included. However, the 'clean' target does not use the $(GITGUI_VERSION) variable, so this is wasted effort. In order to eliminate such wasted effort, use the value of the internal $(MAKECMDGOALS) variable to only '-include GIT-VERSION-FILE' when the target is not 'clean'. (This drops the time down to 0.676s, on my laptop, giving an improvement of 65.05%). Signed-off-by: Ramsay Jones Signed-off-by: Pratyush Yadav --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index f10caedaa7..56c85a85c1 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,9 @@ all:: GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN +ifneq ($(MAKECMDGOALS),clean) -include GIT-VERSION-FILE +endif uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not') From 4d22c0505f85b83f73c580049c74c5a7c7e0a5d4 Mon Sep 17 00:00:00 2001 From: Serg Tereshchenko Date: Sun, 22 Nov 2020 15:32:33 +0200 Subject: [PATCH 39/42] git-gui: Fix selected text colors Added selected state colors for text widget. Same colors for active and inactive selection, to match previous behaviour. Signed-off-by: Serg Tereshchenko Signed-off-by: Pratyush Yadav --- lib/themed.tcl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/themed.tcl b/lib/themed.tcl index 02aae90144..244c061391 100644 --- a/lib/themed.tcl +++ b/lib/themed.tcl @@ -34,8 +34,10 @@ namespace eval color { } add_option *Text.Background $text_bg add_option *Text.Foreground $text_fg - add_option *Text.HighlightBackground $base_bg - add_option *Text.HighlightColor $select_bg + add_option *Text.selectBackground $select_bg + add_option *Text.selectForeground $select_fg + add_option *Text.inactiveSelectBackground $select_bg + add_option *Text.inactiveSelectForeground $select_fg } } From ba2aa15129e59f248d8cdd30404bc78b5178f61d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 17 Dec 2020 15:04:26 -0800 Subject: [PATCH 40/42] Another batch before 2.30-rc1 Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.30.0.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/RelNotes/2.30.0.txt b/Documentation/RelNotes/2.30.0.txt index df8df8a5d1..16955c7e38 100644 --- a/Documentation/RelNotes/2.30.0.txt +++ b/Documentation/RelNotes/2.30.0.txt @@ -391,3 +391,5 @@ Fixes since v2.29 (merge 08e9df2395 jk/multi-line-indent-style-fix later to maint). (merge e66590348a da/vs-build-iconv-fix later to maint). (merge 7fe07275be js/cmake-extra-built-ins-fix later to maint). + (merge 633eebe142 jb/midx-doc-update later to maint). + (merge 5885367e8f jh/index-v2-doc-on-fsmn later to maint). From da4d86da97a316413cf25bef99332525dbfb4d59 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Fri, 18 Dec 2020 10:43:14 +0100 Subject: [PATCH 41/42] git-gui: use gray background for inactive text widgets This makes it easier to see at a glance which of the four main views has the keyboard focus. Signed-off-by: Stefan Haller Signed-off-by: Pratyush Yadav --- git-gui.sh | 18 ++++++++++++------ lib/themed.tcl | 35 +++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index cc6c2aa2c3..201524c34e 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -720,9 +720,6 @@ proc rmsel_tag {text} { -background [$text cget -background] \ -foreground [$text cget -foreground] \ -borderwidth 0 - $text tag conf in_sel\ - -background $color::select_bg \ - -foreground $color::select_fg bind $text break return $text } @@ -3328,11 +3325,20 @@ if {!$use_ttk} { .vpane.files paneconfigure .vpane.files.index -sticky news } +proc set_selection_colors {w has_focus} { + foreach tag [list in_diff in_sel] { + $w tag conf $tag \ + -background [expr {$has_focus ? $color::select_bg : $color::inactive_select_bg}] \ + -foreground [expr {$has_focus ? $color::select_fg : $color::inactive_select_fg}] + } +} + foreach i [list $ui_index $ui_workdir] { rmsel_tag $i - $i tag conf in_diff \ - -background $color::select_bg \ - -foreground $color::select_fg + + set_selection_colors $i 0 + bind $i { set_selection_colors %W 1 } + bind $i { set_selection_colors %W 0 } } unset i diff --git a/lib/themed.tcl b/lib/themed.tcl index 244c061391..f43d84e54f 100644 --- a/lib/themed.tcl +++ b/lib/themed.tcl @@ -6,19 +6,25 @@ namespace eval color { # Variable colors # Preffered way to set widget colors is using add_option. # In some cases, like with tags in_diff/in_sel, we use these colors. - variable select_bg lightgray - variable select_fg black + variable select_bg lightgray + variable select_fg black + variable inactive_select_bg lightgray + variable inactive_select_fg black proc sync_with_theme {} { - set base_bg [ttk::style lookup . -background] - set base_fg [ttk::style lookup . -foreground] - set text_bg [ttk::style lookup Treeview -background] - set text_fg [ttk::style lookup Treeview -foreground] - set select_bg [ttk::style lookup Default -selectbackground] - set select_fg [ttk::style lookup Default -selectforeground] + set base_bg [ttk::style lookup . -background] + set base_fg [ttk::style lookup . -foreground] + set text_bg [ttk::style lookup Treeview -background] + set text_fg [ttk::style lookup Treeview -foreground] + set select_bg [ttk::style lookup Default -selectbackground] + set select_fg [ttk::style lookup Default -selectforeground] + 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 proc add_option {key val} { option add $key $val widgetDefault @@ -36,11 +42,20 @@ namespace eval color { add_option *Text.Foreground $text_fg add_option *Text.selectBackground $select_bg add_option *Text.selectForeground $select_fg - add_option *Text.inactiveSelectBackground $select_bg - add_option *Text.inactiveSelectForeground $select_fg + add_option *Text.inactiveSelectBackground $inactive_select_bg + add_option *Text.inactiveSelectForeground $inactive_select_fg } } +proc convert_rgb_to_gray {rgb} { + # Simply take the average of red, green and blue. This wouldn't be good + # enough for, say, converting a photo to grayscale, but for this simple + # purpose of approximating the brightness of a color it's good enough. + lassign [winfo rgb . $rgb] r g b + set gray [expr {($r / 256 + $g / 256 + $b / 256) / 3}] + return [format "#%2.2X%2.2X%2.2X" $gray $gray $gray] +} + proc ttk_get_current_theme {} { # Handle either current Tk or older versions of 8.5 if {[catch {set theme [ttk::style theme use]}]} { From 6d3ef5b467eccd2769f1aa1c555d317d3c8dc707 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 18 Dec 2020 15:14:30 -0800 Subject: [PATCH 42/42] Git 2.30-rc1 Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.30.0.txt | 4 ++++ GIT-VERSION-GEN | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/RelNotes/2.30.0.txt b/Documentation/RelNotes/2.30.0.txt index 16955c7e38..0190fa6315 100644 --- a/Documentation/RelNotes/2.30.0.txt +++ b/Documentation/RelNotes/2.30.0.txt @@ -393,3 +393,7 @@ Fixes since v2.29 (merge 7fe07275be js/cmake-extra-built-ins-fix later to maint). (merge 633eebe142 jb/midx-doc-update later to maint). (merge 5885367e8f jh/index-v2-doc-on-fsmn later to maint). + (merge 14639a4779 jc/compat-util-setitimer-fix later to maint). + (merge 56f56ac50b ab/unreachable-break later to maint). + (merge 731d578b4f rb/nonstop-config-mak-uname-update later to maint). + (merge f4698738f9 es/perf-export-fix later to maint). diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index c3bbcc9cfa..a3871c7b3d 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.30.0-rc0 +DEF_VER=v2.30.0-rc1 LF=' '