Как получить разницу между рабочими наборами (не коммитами) двух веток git - PullRequest
0 голосов
/ 30 августа 2018

У меня есть следующие две ветви, которые отличаются в файлах

мастер

 |_ document.txt
 |_ document_two.txt
 |_ document_three.txt

развитие

 |_ document.txt
 |_ document_two.txt
 |_ document_three.txt
 |_ virus.exe // want to get rid of that

И это git log результаты обоих ( сверху вниз )

мастер

commit: fdsdfsf1342re5252423425242234 (master, development)
add document one

commit: 563523523g233g5232sdfawe22434 (master, development)
add document two

commit: 56652u747241523g52352fsdfawew (master, development)
add document three

1024 * разработка *

commit: fdsdfsf1342re5252423425242234 (master, development)
add document one

commit: 563523523g233g5232sdfawe22434 (master, development)
add document two

commit: 1213421g233g5232s41dfawe22434 (development)
ADD VIRUS.EXE ! XXX

commit: 5423345652u7433g52352fsdf1223 (development)
change document three completly

commit: 56652u747241523g52352fsdfawew (master, development)
add document three

Цель

Я хочу очистить ветку development , чтобы в ней были все исходные файлы master , а в был удален файл virus.exe.

Я уже нашел способы сделать так, чтобы master перезаписывал состояния файла development .

Читать здесь : Сделать текущую ветку Git главной веткой

Но я также хочу избавиться от файлов, которые не существуют в рабочем наборе master . В этом примере это будет файл virus.exe. Просто создать новую ветку development мастера не вариант, потому что важно оставить ветку development как сирота . При переписывании / ветвлении ветки development с помощью / выключения ветки master он теряет состояние orphan , поскольку он адаптирует всю историю master

Кто-нибудь знает способ:

  • получить различия между двумя ветками в файлах? не их дифференциалы
  • удаление всех найденных различий в файлах путем окончательной фиксации (чтобы сохранить историю нетронутой)?

Редактировать : Я нашел команду, чтобы дать мне разницу в файлах:

$ git diff-tree -r --name-status --diff-filter=A master..development
A       virus.exe

Есть ли элегантный способ непосредственного использования вывода для удаления из ветки разработки? Я хотел бы использовать его в:

git checkout development && git rm virus.exe && git commit -m "clean development" && git push origin

1 Ответ

0 голосов
/ 30 августа 2018

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

Что делают имена веток, это выбирают один конкретный коммит. Этот коммит затем имеет некоторый родительский коммит (или более одного, если это слияние); родитель имеет своего родителя и так далее, образуя цепочку коммитов. В результате мы можем сказать, что ветвь (или имя ветки) содержит некоторый набор коммитов: это коммиты, которые достижимы из имени. Хорошее введение во все это см. Думай как (а) Git .

Каждый коммит имеет сохраненное дерево или снимок. Как вы обнаружили, git diff-tree - это так называемая сантехническая команда (рабочая лошадка, способная работать со скриптами) для сравнения двух деревьев, найденных в двух коммитах:

git diff-tree -r commit1 commit2

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

Вы можете добавить опции, такие как --name-only или --name-status и --find-renames с необязательным значением индекса сходства в процентах, чтобы Git вычислял места, где переименование, а затем изменение, файл производит более короткая последовательность команд, чем простой , удалите файл A и создайте новый файл B с нуля с этим содержимым . Например, возможно, более короткая последовательность - , переименуйте A в B, затем удалите строку 17, , что явно намного короче, чем , удалите файл A, затем создайте файл B с этими 10000 строк: [очень длинный список линий] .

Действующая, ориентированная на пользователя, команда git diff в действительности запускает git diff-tree или git diff-index или что-то еще, но с учетом конфигурации пользователя (например, diff.renames и diff.renameLimit) и с выводом отправляется через пейджер , раскрашен и т. д. Git называет эти команды фарфор , поскольку они должны быть удобными для пользователя (против сантехники, скрытой за стенами, вне поля зрения).

Когда вы делаете новый коммит, у вас в Git сохраняется новый снимок. Git создает новый снимок из того, что Git имеет в своем index во время запуска git commit. parent нового коммита - это старая вершина текущей ветви; новый коммит становится кончиком текущей ветви. Так растут ветви.

Различные команды, которые вы используете, такие как git rm или git add, работают с index . Вы используете git checkout <em>branch</em> для извлечения коммитов веток в этот индекс. Файлы, хранящиеся в в индексе, трудно увидеть - вы можете получить полный список с git ls-files --stage, но это редко очень полезно. Эти файлы, в индексе и (в конечном итоге) замороженные в коммите, все равно находятся в специальной форме Git. Таким образом, чтобы работать с этими файлами, когда у вас есть Git, извлекающий коммит-коммит, у вас также есть Git, извлекающий все файлы в рабочее дерево .

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

Следовательно, если вы сравниваете два коммита (с git diff или git diff-tree), затем вносите некоторые изменения в свой индекс и делаете новый коммит, то, что вы делаете, - это изменение своего индекса и использование его для создания нового коммита. Сравнение двух коммитов зависит от вас. Обратите внимание, что вы также можете сравнить любой один с вашего индекса, используя git diff --cached (фарфор) или git diff-index --cached (сантехника). И вы можете сравнивать индекс с рабочим деревом или коммит с рабочим деревом, также используя эти команды.

...