Как ответвления мерзавца импортируются в подвижный с hg, преобразовывают?

Стек

стопка А, в этом контексте, является методом "последним пришел - первым вышел", буферизуют Вас данные места в то время как Ваши прогоны программы. Метод "последним пришел - первым вышел" (LIFO) означает, что последней вещью, которую Вы вставляете, всегда является первая вещь, которую Вы возвращаете - при продвижении 2 объектов на стеке, и затем 'B', тогда первой вещью, которую Вы выталкиваете от стека, будет 'B', и следующей вещью является 'A'.

, Когда Вы вызываете функцию в своем коде, следующая инструкция после того, как вызов функции хранится на стеке и любом пространстве памяти, которое могло бы быть перезаписано вызовом функции. Функция, которую Вы вызываете, могла бы израсходовать больше стека для своих собственных локальных переменных. Когда это сделано, это освобождает стековое пространство локальной переменной, которое это использовало, затем возвращает предыдущей функции.

Переполнение стека

переполнение стека А состоит в том при израсходовании большей памяти для стека, чем программа, как предполагалось, использовала. Во встроенных системах у Вас могло бы только быть 256 байтов для стека, и если каждая функция поднимает 32 байта тогда, у Вас могут только быть вызовы функции 8 глубоких - функция 1 функция вызовов 2, кто вызывает функцию 3, кто вызывает функцию 4...., кто вызывает функцию 8, кто вызывает функцию 9, но функцию 9 памятей перезаписей вне стека. Это могло бы перезаписать память, код, и т.д.

, Многие программисты делают эту ошибку путем вызывания функции, который тогда вызывает функцию B, который тогда вызывает функцию C, который тогда вызывает функцию A. Это могло бы работать большую часть времени, но только как только неправильный вход заставит его входить в тот круг навсегда, пока компьютер не распознает, что стек раздут.

Рекурсивные функции являются также причиной для этого, но если Вы пишете рекурсивно (т.е., Ваши вызовы функции самого) тогда, необходимо знать об этом и использовать статические / глобальные переменные для предотвращения бесконечной рекурсии.

Обычно ОС и язык программирования, который Вы используете, управляют стеком, и это вне Ваших рук. Необходимо посмотреть граф вызовов (древовидная структура, которая показывает от основного, что каждый вызовы функции), чтобы видеть, как глубоко вызовы функции идут, и обнаружить циклы и рекурсию, которые не предназначаются. Намеренные циклы и рекурсия должны быть искусственно проверены на ошибку, если они называют друг друга слишком много раз.

Вне хороших практик программирования, статического испытания и динамического тестирования, нет очень, можно сделать в этих системах высокого уровня.

Встроенные системы

Во встроенном мире, особенно в высоком коде надежности (автомобильный, самолет, пространство) Вы делаете обширные обзоры кода и проверку, но Вы также делаете следующее:

  • Запрещают рекурсию, и циклы - осуществленный политикой и тестированием
  • Сохраняют код и складывают далеко друг от друга (код во флэш-памяти, стек в RAM, и никогда двойка не должна встречаться)
  • защитные полосы Места вокруг стека - пустая область памяти, которую Вы заполняете магическим числом (обычно инструкция по программному прерыванию, но существует много опций здесь), и сотни или тысячи времен в секунду, Вы смотрите на защитные полосы, чтобы удостовериться, что они не были перезаписаны.
  • защита памяти Использования (т.е., нет выполнитесь на стеке, никаком чтении или записи недалеко от стека)
  • , Прерывания не вызывают вторичные функции - они устанавливают флаги, копируют данные и позволяют приложению заботиться об обработке его (иначе, Вы могли бы получить 8 глубоко в Вашем дереве вызова функции, иметь прерывание, и затем выйти другой немного функций в прерывании, вызвав выброс). У Вас есть несколько деревьев вызова - один для основных процессов, и один для каждого прерывания. Если Ваши прерывания могут прервать друг друга... хорошо, существуют драконы...

Высокоуровневые языки и системы

, Но на высокоуровневых языках работают на операционных системах:

  • Уменьшают Ваше устройство хранения данных локальной переменной (локальные переменные хранятся на стеке - хотя компиляторы довольно умны об этом и будут иногда помещать крупных местных жителей на "кучу", если Ваше дерево вызова мелко)
  • , Избегают или строго ограничивают рекурсию
  • , не разбивают Ваши программы слишком далеко в меньшие и меньшие функции - даже, не считая локальные переменные, каждый вызов функции использует целых 64 байта на стеке (процессор на 32 бита, сохраняя половину регистров ЦП, флагов, и т.д.)
  • Сохраняют Ваше дерево вызова мелким (подобный вышеупомянутому оператору)

веб-серверы

, Это зависит от 'песочницы', которую Вы имеете, можно ли управлять или даже видеть стек. Возможности хороши, можно рассматривать веб-серверы, поскольку Вы были бы любой другой высокоуровневый язык и операционная система - это в основном вне Ваших рук, но проверьте язык и стопку сервера, которую Вы используете. возможно унести стек на Вашем SQL-сервере, например.

-Adam

17
задан DavidM 16 November 2009 в 18:09
поделиться

1 ответ

Это сделано намеренно. Импортированные ветки Git помечены только в Mercurial, и hg Heads должны дать вам правильное количество импортированных «веток».

Как упоминалось в , этот поток :

Рассмотрим дерево, которое выглядит так:

        o-o-o-o-o-o-b <- branch foo
       /
 -o-o-a
       \
        o-o-c <- branch bar

На какой ветви находится «a» и его предки?
У нас нет ни малейшего понятия. Фактически, единственные наборы изменений, в которых мы уверены, - это b nd c, потому что имена веток не являются частью истории.

Итак:

Оказывается, на самом деле это невозможно сделать правильно, потому что git не хранит достаточно информация.
Рассмотрим репо с двумя ветвями в git, в каждой из которых есть несколько коммитов.
Поскольку git не записывает, на какой ветке возникла каждая фиксация, в дереве недостаточно информации, чтобы пометить каждый набор изменений.
Пользователь git может поменять местами имена двух веток, и ничего не записывается, чтобы сказать, что это когда-либо отличалось. Если две ветви имеют общего предка (а они почти наверняка будут), на какой ветке находится этот предок? Мы не знаем.

Лучшее, что мы можем сделать в общем случае, - это пометить каждую головку ветки как находящуюся на этой ветке. Тогда, если вы сделаете инкрементное преобразование, мы, вероятно, поступим правильно. Но концепция ветвей в git не идеальна для hg, поэтому это преобразование тоже не будет идеальным.


Вы можете протестировать его с помощью небольшого репозитория Git (Git 1.6.5.1, Hg1.3.1):

PS C:\Prog\Git\tests> cd .\hgimport
PS C:\Prog\Git\tests\hgimport> git init gitRepoToImport
PS C:\Prog\Git\tests\hgimport> cd .\gitRepoToImport
PS [...]\gitRepoToImport> echo firstContentToBr1 > br1.txt
PS [...]\gitRepoToImport> echo firstContentToBr2 > br2.txt
PS [...]\gitRepoToImport> echo firstContentToBr3 > br3.txt
PS [...]\gitRepoToImport> git add -A
PS [...]\gitRepoToImport> git commit -a -m "first content, to be evolved in three different branches"

Make набор модификаций в трех отдельных ветках:

PS [...]\gitRepoToImport> git checkout -b br1
PS [...]\gitRepoToImport> echo firstEvolutionInBr1 >> .\br1.txt
PS [...]\gitRepoToImport> git commit -a -m "first evolution in branch 1"
PS [...]\gitRepoToImport> echo secondEvolutionInBr1 >> .\br1.txt
PS [...]\gitRepoToImport> git commit -a -m "second evolution in branch 1"
PS [...]\gitRepoToImport> git checkout master
PS [...]\gitRepoToImport> git checkout -b br2
PS [...]\gitRepoToImport> echo firstEvolutionInBr1 >> .\br2.txt
PS [...]\gitRepoToImport> git commit -a -m "first evolution in branch 2"
PS [...]\gitRepoToImport> git checkout master
PS [...]\gitRepoToImport> git checkout -b br3
PS [...]\gitRepoToImport> echo firstEvolutionInBr3 >> .\br3.txt
PS [...]\gitRepoToImport> git commit -a -m "first evolution in branch 3"
PS [...]\gitRepoToImport> echo secondEvolutionInBr3 >> .\br3.txt
PS [...]\gitRepoToImport> git commit -a -m "second evolution in branch 3"
PS [...]\gitRepoToImport> echo thirdEvolutionInBr3 >> .\br3.txt
PS [...]\gitRepoToImport> git commit -a -m "third evolution in branch 3"
PS [...]\gitRepoToImport> git checkout br2
PS [...]\gitRepoToImport> echo secondEvolutionInBr2 >> .\br2.txt
PS [...]\gitRepoToImport> git commit -a -m "second evolution in branch 2"
PS [...]\gitRepoToImport> git checkout br1
PS [...]\gitRepoToImport> echo thirdEvolutionInBr3 >> .\br1.txt
PS [...]\gitRepoToImport> git commit -a -m "third evolution in branch 1"
PS [...]\gitRepoToImport> git checkout br2
PS [...]\gitRepoToImport> echo thirdEvolutionInBr3 >> .\br2.txt
PS [...]\gitRepoToImport> git commit -a -m "third evolution in branch 2"

Затем клонируйте этот репозиторий Git (на всякий случай, в другие мужские тесты)

PS [...]\gitRepoToImport> cd ..
PS C:\Prog\Git\tests\hgimport> git clone .\gitRepoToImport gitRepoToImport1

Настройте свой ~ / .hgrc с форматом UTF-8 без спецификации (мне потребовалось некоторое время, чтобы понять это правильно!)

[extensions]
hgext.convert = 

Затем выполните преобразование

PS C:\Prog\Git\tests\hgimport> hg convert .\gitRepoToImport1 hgRepo
PS C:\Prog\Git\tests\hgimport> cd .\hgRepo
PS C:\Prog\Git\tests\hgimport\hgRepo> hg heads

Вы получите три ожидаемых "ветки"

changeset:   9:ad0884395ada
tag:         tip
user:        VonC
date:        Mon Nov 16 21:45:35 2009 +0100
summary:     third evolution in branch 2

changeset:   6:854bc6537c7c
user:        VonC
date:        Mon Nov 16 21:45:19 2009 +0100
summary:     third evolution in branch 1

changeset:   3:9194cf25d3ca
user:        VonC
date:        Mon Nov 16 21:44:09 2009 +0100
summary:     third evolution in branch 3
21
ответ дан 30 November 2019 в 13:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: