Подтвердить что ты не робот

Git merge: Удаление файлов, которые я хочу сохранить!

Как вы можете объединить две ветки в git, сохраняя необходимые файлы из ветки?

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

Например:

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

Как воспроизвести:

  • Создайте репозиторий git с одним файлом.

    git init
    echo "test" > test.txt
    git add .
    git commit -m "initial commit"
    
  • Создать ветку

    git branch branchA
    
  • Удалить файл в главном

    git rm test.txt
    git commit -m "removed file from master"
    
  • Сделать ЛЮБЫЕ изменения в ветке А, которые не касаются удаленного файла (он должен быть неизменным, чтобы избежать конфликта)

    git checkout branchA
    touch something.txt
    git add .
    git commit -m "some branch changes"
    

Отсюда, любым способом, который я нашел, чтобы объединить эти две ветки, файл test.txt удаляется. Предполагая, что мы полагаемся на файл для branchA, это большая проблема.


Неудачные примеры:

Объединить 1

git checkout branchA
git merge master
ls test.txt

Объединить 2

git checkout master
git merge branchA
ls test.txt

Rebase 1

git checkout branchA
git rebase master
ls test.txt
4b9b3361

Ответ 1

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

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

git checkout [email protected]{1} .
git merge --no-commit master
git checkout master test.txt
git add test.txt
git commit

Ответ 2

Для быстрого исправления в этом случае "git вернуть" коммит, который удалил файл.

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

Ответ 3

Вам нужно изменить файл в ветке, чтобы конфликт слиянием удалился в соединительной линии.

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

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

Ответ 4

Пример Casey не работал для моего случая - я не мог проверить test.txt из master, потому что он больше не находился в этой ветке:

$ git checkout master test.txt
error: pathspec 'test.txt' did not match any file(s) known to git.

К счастью, я мог вытащить файл из branchA собственного HEAD:

$ git checkout branchA
$ git merge --no-commit master
$ git checkout HEAD test.txt
$ git add test.txt
$ git commit

Ответ 5

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

Моя история прошла примерно так. Имена веток были изменены для защиты невинных.

  • создавать и фиксировать файлы для новой функции для мастеринга
  • поймите, что это дополнение будет более активным, чем первоначально планировалось, таким образом, разветвленное до feature_branch
  • Удалены файлы с мастера, чтобы не нарушать нормальный рабочий процесс с помощью RB и таких
  • Время проходит, больше фиксируется на хозяине, нет на feature_branch
  • Возобновить работу над функцией, git merge master на feature_branch, чтобы исходные файлы были удалены (конечно), git reset --hard до слияния
  • Применил описанное выше решение.