Как экспортировать историю пересмотра из подвижного или мерзавца к cvs?

Это действительно возможно, но Microsoft почему-то не документировала его. API NtQuerySection существовал с ранних версий Windows NT и до сих пор работает в Windows 10.

Итак, вот как вы это делаете (очевидно, на свой риск полагаться на недокументированный API ядра):

HANDLE hFileMapping = ::OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, strSharedMemName);
_ASSERT(hFileMapping);

ULONGLONG uicbSharedMemSize = 0;

//Get the handle returned by the CreateFileMapping function
//Assuming the same process here...
HANDLE hDupH;
if((::DuplicateHandle(
    ::GetCurrentProcess(), hFileMapping, 
    ::GetCurrentProcess(), &hDupH,
    DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS, FALSE, 0)))
{
    hFileMapping = hDupH;

    enum SECTION_INFORMATION_CLASS{
        SectionBasicInformation,
        SectionImageInformation
    };

    typedef struct _SECTION_BASIC_INFORMATION {
      ULONG                   Unknown;
      ULONG                   SectionAttributes;
      LARGE_INTEGER           SectionSize;
    } SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;

    static NTSTATUS
    (NTAPI
    *pfnNtQuerySection)(
      IN HANDLE               SectionHandle,
      IN SECTION_INFORMATION_CLASS InformationClass,
      OUT PVOID               InformationBuffer,
      IN ULONG                InformationBufferSize,
      OUT PULONG              ResultLength OPTIONAL ) = NULL;

    if(!pfnNtQuerySection)
        (FARPROC&)pfnNtQuerySection = ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), "NtQuerySection");

    if(pfnNtQuerySection)
    {
        SECTION_BASIC_INFORMATION sbi = {0};
        ULONG ucbRead = 0;
        NTSTATUS stat = pfnNtQuerySection(hFileMapping, SectionBasicInformation, &sbi, sizeof(sbi), &ucbRead);
        if(stat >= 0)
        {
            //The size returned will be rounded up to the page size (i.e. 4K in most cases)
            uicbSharedMemSize = sbi.SectionSize.QuadPart;
        }
    }
}

в первую очередь правильное определение для SECTION_BASIC_INFORMATION:

typedef struct _SECTION_BASIC_INFORMATION
{
    PVOID BaseAddress;
    ULONG AllocationAttributes;
    LARGE_INTEGER MaximumSize;
} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;

, поэтому старое определение (с DWORD первым членом - было неправильным и не будет работать для 64-битный код).

в секунду для вызова NtQuerySection дескриптор раздела должен иметь доступ SECTION_QUERY, в противном случае будет STATUS_ACCESS_DENIED - поэтому строка:

OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, strSharedMemName);

неверна , должен быть

OpenFileMapping(SECTION_QUERY|FILE_MAP_READ|FILE_MAP_WRITE, FALSE, strSharedMemName);

или любым доступом, в том числе SECTION_QUERY

отметить, что если использовать OpenFileMapping и установить dwDesiredAccess точно на SECTION_QUERY, OpenFileMapping по неизвестной причине измените его на SECTION_MAP_READ - это следующая строка кода внутри этого api. if (dwDesiredAccess == SECTION_QUERY) dwDesiredAccess = SECTION_MAP_READ;, поэтому необходимо добавить некоторый доступ к SECTION_QUERY. конечно, мы можем использовать SECTION_QUERY точно с ZwOpenSection

next - для какого вызова DuplicateHandle?!? это абсолютно бессмысленно в вызове контекста задачи. мы получили управление секцией через OpenFileMappingW или ZwOpenSection.

и, наконец, для чего GetModuleHandle + GetProcAddress для ZwQuerySection? как нам интересно называть OpenFileMappingW без GetModuleHandle + GetProcAddress, например? как GetProcAddress звонит? так же мы можем вызвать ZwQuerySection - просто ссылку с ntdll.dll через ntdll.lib , которые существуют в каждой папке wdk lib. поэтому окончательный код должен быть:

if (HANDLE hMap = OpenFileMappingW(SECTION_QUERY|SECTION_MAP_READ, FALSE, name))
{
    SECTION_BASIC_INFORMATION sbi;
    if (0 <= ZwQuerySection(hMap, SectionBasicInformation, &sbi, sizeof(sbi), 0))
    {
        DbgPrint("section size = %I64x\n", sbi.Size.QuadPart);
    }
    CloseHandle(hMap);
}

или

HANDLE hMap;
if (0 <= ZwOpenSection(&hMap, SECTION_QUERY, &oa))
{
    SECTION_BASIC_INFORMATION sbi;
    if (0 <= ZwQuerySection(hMap, SectionBasicInformation, &sbi, sizeof(sbi), 0))
    {
        DbgPrint("section size = %I64x\n", sbi.Size.QuadPart);
    }
    CloseHandle(hMap);
}

101
задан skiphoppy 25 March 2009 в 19:35
поделиться

3 ответа

К счастью, для тех из нас, кто все еще вынужден использовать CVS, мерзавец обеспечивает довольно хорошие инструменты, чтобы сделать точно, что Вы желаете сделать. Мои предложения (и что мы делаем здесь на уровне $work):

Создание Начального Клона

Использование git cvsimport для клонирования истории пересмотра CVS в репозиторий мерзавца. Я использую следующий вызов:

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout

-A опция является дополнительной, но она помогает сделать Вашу историю пересмотра, это импортируется из более подобного мерзавцу взгляда CVS (см. man git-cvsimport для большего количества информации о том, как это настраивается).

В зависимости от размера и истории репозитория CVS, этот первый импорт займет Очень долгое время. Можно добавить-v к вышеупомянутой команде, если Вы хотите душевное спокойствие, что что-то на самом деле происходит.

, Как только этот процесс завершается, Вы будете иметь master ответвление, которое должно отразить ГОЛОВУ CVS (за исключением того, что git cvsimport по умолчанию игнорирует ценность прошлых 10 минут фиксаций, чтобы не ловить фиксацию, которая наполовину закончена). Можно тогда использовать git log и друзья для исследования всей истории репозитория так же, как если бы это использовало мерзавца с начала.

Тонкие настройки Конфигурации

существуют несколько тонких настроек конфигурации, которые сделают возрастающий импорт из CVS (а также экспорт) легче в будущем. Они не документируются на git cvsimport страница справочника, таким образом, я предполагаю, что они могли измениться без уведомления, но, FWIW:

% git config cvsimport.module cvs_module_to_checkout
% git config cvsimport.r cvs
% git config cvsimport.d $CVSROOT

Все эти опции могут быть определены на командной строке, таким образом, Вы могли безопасно пропустить этот шаг.

Возрастающий Импорт

Последующий git cvsimport должен быть намного быстрее, чем первый вызов. Это действительно, однако, делает cvs rlog на каждом каталоге (даже те, которые имеют только файлы в [1 118]), таким образом, может все еще потребоваться несколько минут. Если Вы определили предложенные конфигурации выше, все, что необходимо сделать, выполнитесь:

% git cvsimport

, Если Вы не настроили свои конфигурации для определения значений по умолчанию, необходимо будет определить их на командной строке:

% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout

Так или иначе, две вещи иметь в виду:

  1. Удостоверяются, что Вы находитесь в корневом каталоге Вашего репозитория мерзавца. Если Вы еще будете везде, то это попытается сделать новое cvsimport, который снова возьмет навсегда.
  2. Удостоверяются, что Вы находитесь на Вашем master ответвление так, чтобы изменения могли быть объединены (или перебазирующимися) в Ваши локальные ответвления / ответвления темы.

Вносящие Локальные Изменения

На практике, я рекомендую всегда внести изменения на ответвлениях и только объединиться с [1 121], когда Вы готовы экспортировать, они возвращаются в репозиторий CVS. Можно использовать любой рабочий процесс, который Вы любите на своих ответвлениях (слияние, перебазирование, сплющивание, и т.д.), но конечно стандартные правила перебазирования применяются: не повторно базируйтесь, если кто-либо еще основывал их изменения на Вашем ответвлении.

Изменения Экспорта в CVS

Эти git cvsexportcommit управляют, позволяет Вам экспортировать выбрать фиксацию в сервер CVS. Можно определить единственный идентификатор фиксации (или что-либо, что описывает определенную фиксацию, как определено в [1 135] man git-rev-parse ). Разность тогда сгенерирована, относится контроль CVS и затем (дополнительно) предана CVS с помощью фактического cvs клиент. Вы могли экспортировать каждую микро фиксацию на своих ответвлениях темы, но обычно мне нравится создавать фиксацию слияния на актуальном master и экспорт, что единственное слияние соглашается на CVS. При экспорте фиксации слияния необходимо сказать мерзавцу, которые передают родителя для использования для генерации различного. Кроме того, это не будет работать, если Ваше слияние было ускоренной перемоткой вперед (см. раздел "HOW MERGE WORKS" [1 136] man git-merge для описания слияния ускоренной перемотки вперед), таким образом, необходимо использовать --no-ff опция при выполнении слияния. Вот пример:

# on master
% git merge --no-ff --log -m "Optional commit message here" topic/branch/name
% git cvsexportcommit -w /path/to/cvs/checkout -u -p -c ORIG_HEAD HEAD

Вы видите то, что каждую из тех опций означают на страница справочника для мерзавца-cvsexportcommit . У Вас действительно есть опция установки -w опция в Вашей конфигурации мерзавца:

% git config cvsexportcommit.cvsdir /path/to/cvs/checkout

, Если сбои патча по любой причине, мой опыт состоит в том, что Вы (к сожалению), вероятно, будете более обеспеченным копированием переключенных файлов вручную и фиксацией использования cvs клиента. Этого не должно происходить, однако, если Вы удостоверяетесь master, актуально с CVS прежде, чем объединить Ваше ответвление темы в.

, Если фиксация перестала работать по любой причине (проблемы сети/полномочий, и т.д.), можно принять управление, распечатанное к терминалу в конце вывода ошибок, и выполнить ее в CVS рабочий каталог. Это обычно выглядит примерно так:

% cvs commit -F .msg file1 file2 file3 etc

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

Клонирование Вашего клона CVS

, Если бы у Вас есть больше чем один человек, бывший должный сделать эти cvsimport, было бы более эффективно иметь единственный репозиторий мерзавца, который выполняет cvsimport, и создайте все другие репозитории как клон. Это работает отлично, и клонированный репозиторий может выполнить cvsexportcommits, столь же описанный выше. Существует один протест, как бы то ни было. Из-за пути фиксации CVS возвращаются через с различными идентификаторами фиксации (как описано выше), Вы не хотите, чтобы Ваше клонированное ответвление отследило центральный репозиторий мерзавца. По умолчанию это - то, как git clone настраивает Ваш репозиторий, но это легко исправлено:

% git clone [CENTRAL_REPO_HERE]
% cd [NEW_GIT_REPO_DIR_HERE]
% git config --unset branch.master.remote
% git config --unset branch.master.merge

после удаления этих конфигураций необходимо будет явно сказать, где и что вытянуть от того, когда Вы хотите вытянуть в новых фиксациях от центрального репозитория:

% git pull origin master
<час>

В целом, я нашел, что этот рабочий процесс довольно управляем и "следующая лучшая вещь", когда миграция полностью на мерзавца не практична.

238
ответ дан sigjuice 5 November 2019 в 11:40
поделиться

В дополнение к ответу Brian Phillips: существует также мерзавец-cvsserver , который функционирует как сервер CVS, но на самом деле репозиторий мерзавца доступа..., но он имеет некоторые ограничения.

3
ответ дан Jakub Narębski 5 November 2019 в 11:40
поделиться

Не следует слепо доверять cvsimport и проверять, совпадает ли импортированное дерево с тем, что находится в репозитории CVS. Я сделал это, поделившись новым проектом с помощью подключаемого модуля eclipse CVS, и обнаружил несоответствия.

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

Я смог решить эту проблему, изменив параметр 'fuzz' на значение менее минуты.

пример:

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout -z 15

нижняя строка: проверьте свое дерево после импорта

22
ответ дан 24 November 2019 в 04:37
поделиться
Другие вопросы по тегам:

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