Автоматически переписывать историю git для выпуска с открытым исходным кодом

В настоящее время я выпускаю несколько проектов с открытым исходным кодом. Обычно полный исходный код предоставляется в виде ZIP-архива или регистрируется в репозитории с открытым исходным кодом. Это затрудняет анализ с помощью ohloh.

Если программное обеспечение было разработано в непубличном репозитории, доступна полная история. Однако я не хочу, чтобы была опубликована полная история.

Я хочу использовать git для достижения одной из двух возможностей:

(i) Одна фиксация для каждого автора: должна быть одна фиксация для каждого автора (с датой фиксации в качестве окончательной даты выпуска). Каждый коммит содержит строки кода, которые в итоге попали в окончательную версию.

(ii) Исходные фиксации только с последними строками кода: В этом варианте количество самих фиксаций сохраняется. Каждый коммит модифицируется таким образом, что сохраняются только те строки, которые наконец попали в финальную версию, а все остальные удаляются.

Кто-нибудь уже реализовал один из вариантов? Вариант (i) кажется выполнимым с использованием git-blame и немного сценариев.


person koppor    schedule 14.07.2012    source источник
comment
Из любопытства, почему такой подход? Является ли это подмножеством вашего полного частного репозитория.   -  person Thorbjørn Ravn Andersen    schedule 14.07.2012
comment
Причины конфиденциальности. Я пообещал коммиттерам, что их коммиты не будут доступны для публики. В основном это студенты, изучающие программирование. Я не хочу, чтобы их ошибки и часы работы были доступны общественности. - Вы помните CrossPoint (программное обеспечение для фидонетов?) Там можно было установить время создания почты на 00:00, чтобы обеспечить немного конфиденциальности :)   -  person koppor    schedule 15.07.2012
comment
Copybara от Google и его предшественник MOE, похоже, преследует схожие цели. Они даже позволяют синхронизировать частные и общедоступные репозитории. Необходимы дальнейшие исследования, действительно ли они могут обеспечивать те же функции.   -  person koppor    schedule 10.07.2017
comment
(Отказ от ответственности, я инженер Google, работающий над Copybara). Копибара должна делать то, что вы хотите. Он может фильтровать коммиты с помощью origin_files, а также очищать информацию из сообщения коммита или файлов (мы не рекомендуем это делать, чтобы миграция была обратимой, и вы могли импортировать запросы на вытягивание от ваших внешних участников). Мы также поддерживаем несколько видов преобразований. Режим i) - это то, что мы называем режимом SQUASH, а MODE ii) ИТЕРАТИВНЫМ. CHANGE_REQUEST — это режим, который позволяет импортировать обратно вклады из репозиториев, не являющихся источником правды (кто-то отправляет вам запрос на включение в общедоступный репозиторий).   -  person Mikel    schedule 22.08.2017
comment
@Mikel Спасибо за ваш комментарий. После работы над git-oss-releaser я обнаружил как Copybara, так и его предшественника MOE. Я поместил его в README.md как связанные проекты: github.com/koppor/ git-oss-releaser#related-projects. Я был так свободен, чтобы включить ваш комментарий в README.md. Я надеюсь, это нормально для вас!   -  person koppor    schedule 22.08.2017
comment
да, звучит хорошо :)   -  person Mikel    schedule 23.08.2017


Ответы (2)


(i) Одна фиксация на автора

Я предполагаю, что это логически невозможно: предположим, у вас есть последовательность коммитов, подобная этой:

  • Коммит: A, Автор: Альфа
  • Коммит: B, Автор: Бета
  • Коммит: C, Автор: Альфа

Если фиксация C зависит от чего-либо, сделанного в B, вы больше не можете переупорядочивать и сжимать A и C.

(ii) Исходная фиксация только с последними строками кода

Для этого вы можете использовать «git filter-branch --tree-filter». Остерегайтесь, что следующий скрипт может съесть котят, потому что я тестировал его только на простом тестовом репозитории. Вас предупредили:

git filter-branch --prune-empty --tree-filter '
    # directory which contains the final version of the project
    FINAL_VERSION="$DIRECTORY_WITH_REPOSITORY_OF_FINAL_VERSION"

    # directory which contains the filtered version of the repository
    FILTER_DIR="$(pwd)"

    # apply the current commit in to the final version in reverse mode,
    # ignore the rejects
    cd "$FINAL_VERSION"
    git show "$GIT_COMMIT" > /tmp/original.patch
    cat /tmp/original.patch | patch -p1 -t
    git diff > /tmp/filtered.patch

    # reset the FINAL_VERSION to the original state.
    git reset --hard
    git clean -f -d -x

    # apply the patch which contains the lines which could be reversed on
    # the filtered version
    cd "$FILTER_DIR"
    # revert the last commit
    patch -p1 -t < /tmp/original.patch

    # apply the filtered patch
    patch -p1 -t < /tmp/filtered.patch
    # remove the rejects by the modified patch 
    find -name "*.orig" -o -name "*.rej" | xargs rm -rf
' previousRelease..HEAD    

(это предполагает, что вы пометили точку ветвления с помощью «previousRelease». Вам также необходимо адаптировать переменную FINAL_VERSION.)

person andlaus    schedule 15.07.2012

git-oss-releaser — это решение для варианта (i).

git-oss-releaser преобразует данный репозиторий git в репозиторий git, содержащий только файлы последнего коммита, и фиксирует вывод, напоминающий git blame для каждого файла. Первоначальная история утеряна.

использование: git-oss-releaser.py [-h] repoDir outDir

Позиционные аргументы:

  • repoDir: Репозиторий для преобразования. Также может быть подкаталогом репозитория.
  • outDir: каталог, в котором должен быть создан новый репо. Должен быть пуст.

Необязательные аргументы:

  • --name NAME user.name для фиксации файлов. По умолчанию глобальный user.name git.
  • --email EMAIL user.email для фиксации файлов. По умолчанию глобальный user.email git.
  • --date DATE Дата, используемая для коммитов. По умолчанию используется дата последней фиксации.

Обратите внимание, что git различает автора и коммиттера при коммите. Автор берется с помощью git blame, данные коммиттера берутся из глобальных user.name и user.emailили заданных настроенных --name и --email.

В настоящее время режим DEBUG можно включить только в коде.

Ограничения

  • Работает только с репозиториями git без каких-либо неотслеживаемых файлов.
  • Пустые строки назначаются «git-oss-releaser», а не первому или последнему автору, добавляющему эти пустые строки.
  • Репозиторий должен содержать хотя бы один небинарный файл
  • Дата фиксации берется только из небинарных файлов
  • Протестировано под git только для Windows
person koppor    schedule 22.07.2012
comment
@downvoters: Пожалуйста, объясните, почему вы минусуете мой ответ. - Я расширил его сейчас, чтобы быть более автономным. - person koppor; 07.02.2017