Создайте git commit C, который является обратной величиной разницы B и A - PullRequest
1 голос
/ 23 марта 2019

Итак, у меня есть git-репозиторий, над которым я работал годами один на один. По сути, я использовал только одну ветку (MASTER), а git был для меня как журнал. Теперь я хочу сделать этот исходный код общедоступным, но я хочу удалить файлы, для которых у меня нет разрешения на повторное распространение. Я также хотел бы удалить некоторые комментарии, которые я не хочу публиковать.

Эти личные комментарии и нераспространяемые файлы по-прежнему важны для меня.

Допустим, мой самый последний коммит называется A. Я могу сделать публичную ветвь (PUBLIC), удалить все, что не может быть общедоступным, и сделать новый коммит. Мы назовем этот новый коммит B. Затем я могу клонировать этот репозиторий с помощью нескольких опций, стереть историю, а затем опубликовать новый репозиторий и ветвь. Затем я могу работать в этой общедоступной ветке с моими будущими сотрудниками.

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

Есть ли способ создать третью ветку (PRIVATE) с новым коммитом C, представляющую разницу между A и B?

Например:

Commit A (MASTER)
 |  |   - File 1 (text file)
 |  |   - File 2 (text file)
 |  |   - File 3 (binary file)
 |  |   - File 4 (text file)
 |  |   - File 5 (text file)
 |  |   - File 6 (text file)
 |  |   - File 7 (text file)
 |  |   - File 8 (text file)
 |  |   - File 9 (text file)
 |  |
 |  Commit B (PUBLIC)
 |     - File 1 (text file)
 |     - File 2 (text file)
 |     - File 4 (text file)
 |     - File 7 (same except for line 2 removed)
 |     - File 8 (same except for line 4 edited)
 |     - File 9 (same except for a new line inserted between line 8 and line 9)
 |     - File 10 (new text file)
 |     - File 11 (new binary file)
 |
Commit C (PRIVATE)
   - File 3 (binary file)
   - File 5 (text file)
   - File 6 (text file)
   - File 7 (only shows line 2)
   - File 8 (only shows the original line 4)

Обычно я пытаюсь взять ветку MASTER, разветвлять ее в новую ветку PUBLIC, а затем автоматически разветвлять ветку MASTER в новую ветку PRIVATE, последняя фиксация которой не содержит ничего в последней фиксации PUBLIC. По сути, я хочу автоматически разделить или разделить ветку MASTER, просто удалив вещи.


Обновление

Одна вещь, которую я сделал, после создания Commit B в ветке PUBLIC, переключитесь на ветку PRIVATE, затем запустите

rm -r *
git diff --binary --no-ext-diff B..A|git apply --reject

Это будет работать для File 3, File 5, File 6, но для File 7 и File 8 выдает ошибку No such file or directory.

Если вместо этого запустить

rm -r *
touch "File 7"
touch "File 8"
git diff --unified=0 --binary --no-ext-diff B..A|git apply --reject

Это будет работать для File 3, File 5, File 6 и File 7, но для File 8 вместо этого он помещает некоторые данные (измененную строку) в файл с именем File 8.rej. Это приближается к тому, что я хочу, но использование команды touch здесь нецелесообразно, так как я не буду знать, какие файлы действительно изменились.


Обновление 2

Я могу использовать следующее для автоматического прикосновения к измененным файлам:

git diff --diff-filter=M -z --name-only B..A| xargs -0 -IREPLACE touch REPLACE

Я также могу использовать:

find . -type f -name '*.rej' -print0 | xargs -0 rename -f 's/.rej$//'

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

На данный момент я выбираю

rm -r *
git diff --diff-filter=M -z --name-only B..A| xargs -0 -IREPLACE touch REPLACE
git diff --binary --no-ext-diff B..A|git apply --reject

Пропуск опции --unified=0 помещает как удаление строк, так и изменения строк в файлы .rej (я получаю File 7.rej и File 8.rej).

В этом случае, что я получаю в ветке PRIVATE: все файлы, удаленные в ветке PUBLIC, восстанавливаются, любые файлы с удалениями или изменениями, я получаю в основном индивидуальный diff для каждого файла, в своем собственном файл. Я также предпочитаю просто оставить там файлы .rej, поскольку, как уже упоминалось выше, я не знаю, насколько это безопасно.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...