Git слияние с переименованными файлами

У меня есть большой веб-сайт, который я перехожу в новую структуру и в процессе добавления git. На текущем сайте нет контроля над версиями.

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

Теперь, когда я работал над новым сайтом, были внесены изменения в файлы на старом сайте. Поэтому я переключился на мастер и скопировал все эти изменения.

Проблема заключается в том, что я объединяю ветвь с новой структурой обратно на master, есть конфликт на каждом файле, который был изменен на главной ветке.

Я не стал бы беспокоиться об этом, но есть несколько сотен файлов с изменениями. Я пробовал git rebase и git rebase --merge без везения.

Как я могу объединить эти 2 ветки без обращения к каждому файлу?

Ответ 1

Я понял, что исправить. Поскольку переименование файлов было выполнено с помощью script, я смог скопировать новые .php файлы и перезапустить script до слияния. Поскольку файлы имеют одинаковое имя, слияние работает без конфликтов.

Вот шаги для всего процесса.

  • Создать git repo git init
  • Скопировать существующие файлы в
  • Фиксировать
  • Запустите script, чтобы переименовать файлы
  • Фиксировать
  • Создайте ветку, но не проверяйте ее
  • Сделайте исправления, вносимые изменениями, когда вы идете
  • Оформить заявку на отделение, которое вы сделали на шаге 6
  • Скопировать новые версии файлов
  • Запустите script, чтобы переименовать файлы (это должно заменить те из первого запуска)
  • Фиксировать
  • Мастер проверки
  • объединить ветвь в мастер

Это работает, потому что для git были внесены изменения в файлы с новым именем.

Ответ 2

Так как git 1.7.4, вы можете указать порог переименования для слияния как git merge -X rename-threshold=25, чтобы контролировать, что сходство 25% уже достаточно, чтобы рассмотреть два файла, переименовывающих кандидатов. Это, в зависимости от случая вместе с -X ignore-space-change, может сделать переименование более надежным.

Однако я хотел иметь более прямой контроль и готовил связанные с ним script последние дни. Может быть, это помогает - сообщите мне.

https://gist.github.com/894374

Ответ 3

Должна работать автоматически, благодаря обнаружению переименования. Ниже приведен пример сеанса:

$ git init test
Initialized empty Git repository in /tmp/jnareb/test/.git/
$ cp ~/git/README .    # example file, large enough so that rename detection works
$ git add .
$ git commit -m 'Initial commit'
[master (root-commit) b638320] Initial commit
 1 files changed, 54 insertions(+), 0 deletions(-)
 create mode 100644 README
$ git checkout -b new-feature        
Switched to a new branch 'new-feature'
$ git mv README README.txt
$ git commit -m 'Renamed README to README.txt'
[new-feature ce7b731] Renamed README to README.txt
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename README => README.txt (100%)
$ git checkout master
Switched to branch 'master'
$ sed -e 's/UNIX/Unix/g' README+ && mv -f README+ README
$ git commit -a -m 'README changed'
[master 57b1114] README changed
 1 files changed, 1 insertions(+), 1 deletions(-)
$ git merge new-feature 
Merge made by recursive.
 README => README.txt |    0
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename README => README.txt (100%)

Если вы делали "git merge master" в ветке "новая функция" вместо, как и выше, "git merge new-feature" на "master", вы получите:

$ git merge master
Merge made by recursive.
 README.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

Не могли бы вы рассказать, что вы делали по-другому?

Обратите внимание, что обычная "git rebase" (и "git pull --rebase" ) не забирает переименования: вам нужно запустить "git rebase -m" или интерактивную rebase.

Ответ 4

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

Дано:

fileA: A modified file that was moved to the new place but is currently in the old place.
destB: The location where fileB was moved to. This could include a new filename.

Запустите следующие команды:

git add fileA
git mv fileA destB

Это все, что я должен был сделать. Затем я совершил и перебазирование продолжалось.

Ответ 5

Добавляя к ответу @Tilman, с последним git параметр переименования -X find-renames=<n>