После конфликта слияния Git, многие файлы, к которым я не прикасался, становятся изменениями для фиксации. - PullRequest
29 голосов
/ 08 февраля 2012

Итак, я работаю в ветке, внесу некоторые изменения и запускаю git merge master. Я получаю конфликт слияния с одним из измененных файлов (с которым я знаю, как обращаться), но по какой-то причине куча файлов, которые я сделал , а не touch (но которые неожиданно были обновлены в master) введите мой список "Изменения должны быть совершены".

Почему это? И как мне это исправить? Я не хочу, чтобы какие-либо из этих не-мной изменений были зафиксированы.

Ответы [ 6 ]

4 голосов
/ 09 октября 2013

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

Предположим, ваша рабочая ветка называется topic-branch.

Вместо того, чтобы делать:

$ git merge master

вы могли бы сделать:

$ git checkout master
$ git merge topic-branch

На английском языке вместо слияния ветви masterв topic-branch вы могли бы слить topic-branch в master.

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

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

Проблема, с которой вы столкнулись, заключается в том, чтобы просто merge пытаться выполнить свою работу.Файлы не изменяются в вашей ветке тем, но они находятся в той ветке, в которую вы объединяетесь.Если вы посмотрите на это в противоположном направлении слияния topic-branch в master, проблема исчезнет, ​​потому что она рассматривает только файлы, которые вы изменили.

Концептуально, вот что делает слияние (подробнее здесь ):

Пусть текущая головка называется текущей, а объединяемая головка называется слиянием.

  1. Идентифицирует общего предка токаи слить.Назовите это предком-коммитом.
  2. Разобраться с легкими случаями.Если предок-коммит равен слиянию, то ничего не делать.Если предок-коммит равен току, выполните ускоренное слияние .
  3. В противном случае определите изменения между коммитом-предком и слиянием.
  4. Попытка объединить эти изменения с текущими файлами.
  5. Если не было конфликтов, создайте новый коммит с двумя родителями, current и merge.Установите current (и HEAD), чтобы он указывал на этот новый коммит, и соответственно обновите рабочие файлы для проекта.
  6. Если произошел конфликт, вставьте соответствующие маркеры конфликта и сообщите об этом пользователю.Фиксация не создана.
4 голосов
/ 12 апреля 2012

Я думаю, что проблема с этим способом GIT заключается в том, что после коммита будет выполняться «push». «Push» будет включать в себя все зафиксированные файлы, включая файлы, которые «pusher» не трогал. Это усложняет отслеживание изменений.

2 голосов
/ 08 февраля 2012

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

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

Что касается того, что «я не хочу, чтобы какие-либо изменения, сделанные не мной, были зафиксированы», почему вы вообще сделали слияние, если не хотите никаких изменений?

0 голосов
/ 16 ноября 2018

Способ воспроизвести проблему

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

mkdir a
cd a
git init

создать a/alpha.docx и сохранить его, затем продолжить с

git add alpha.docx
git commit -m "initial alpha commit"

Создать репо b с удаленным a:

cd ..
mkdir b
cd b
git clone ../a

Измените a/alpha.docx и сохраните его, затем продолжите с

cd ../a
touch beta                        # create some file
git commit -am "modified alpha"

Откройте b/alpha.docx в слове и начните что-то печатать. Не сохраняйте это. Это помечает файл как занятый.

cd ../b
git pull

Это создаст файл b/beta, а затем прервет слияние с этой ошибкой:

remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /cygdrive/c/tmp2/b/../a
   a797c43..5c6796e  master     -> origin/master
Updating a797c43..5c6796e
error: unable to unlink old 'alpha.docx': Device or resource busy

Если вы сейчас попытаетесь снова потянуть, после закрытия слова и отмены локальных изменений, это произойдет:

$ git pull
Updating a797c43..5c6796e
error: The following untracked working tree files would be overwritten by merge:
        beta
Please move or remove them before you merge.
Aborting

Как с этим бороться

Путь 1

git reset --hard HEAD
git clean -f -d
git pull

как предложено здесь

Путь 2

git add -A
git stash
git pull
git stash drop  # optional

Почему это

Я не знаю. Рекомендуем редактировать этот раздел, если вы знаете это.
Лично я ожидал, что git удалит все новые файлы при прерывании слияния. Цитировать ответ Нуфа Ибрагима выше:

Новый коммит со всеми изменениями из исходной ветки создается в площадка для постановки. В случае конфликта этот процесс обновления область постановки прерывается и вам предоставляется контроль. Вот почему это происходит.

0 голосов
/ 26 сентября 2018

Где я могу найти это всплывающее окно, если я:

1) создать и работать на ветке (b1)

---m
    \
     b1

---m
    \
      ---b1

2) создать новую ветвь (b2) из ​​b1, в течение которой кто-то другой вносит изменения в полностью несвязанный код в master

----------------m
    \
      ---b1
          \
           b2

3) вернитесь и внесите некоторые изменения в b1, а затем перетащите b1 в мастер.

----------------m
    \          /
      -------b1
          \
            --b2

Если я тогда попытаюсь перейти от мастера к b2, я получу конфликт из-за изменений, внесенных в b1 после создания b2. Если я исправлю конфликт, результирующая фиксация будет включать все изменения, которые произошли на master со времени ветки b1, как если бы я их выполнил. (git blame, кажется, может сказать оригинальному автору)

В этом сценарии, если я вместо этого сначала вытащу из b1 в b2 и разберу там слияние, то я смогу вытащить из мастера без проблем, и извлеченные ненужные коммиты не будут отображаться как изменения I ' мы сделали.

git merge --abort ваш друг, если вы находитесь в середине слияния, полного коммитов, которые вы не сделали.

0 голосов
/ 27 апреля 2018

Я сам столкнулся с той же проблемой и нашел промежуточное решение. Нужно найти лучшего в будущем.

Сначала ответим на вопрос, заданный @NoufalIbrahim: Что касается «Я не хочу, чтобы какие-либо изменения, сделанные не мной, были зафиксированы». Почему вы вообще сделали слияние, если не хотите какие-нибудь изменения?

Вы неправильно поняли намерение @grautur. Изменения необходимы, но не как часть нового коммита. Например, 1 файл был добавлен локально, 100 файлов пришли из слияния. Новый коммит должен иметь 1 измененный файл, а не 101 измененный файл. Это особенно важно, если автоматическое объединение невозможно, но инициируется запрос на удаление, и кто-то должен просмотреть коммит. Вы хотите, чтобы рецензент просмотрел 1 файл, а не 101 файл.

Что я сейчас делаю, так это: скажем, у нас есть ветка 'master' и 'feature'. 'feature' создается из 'master', и я только изменяю файлы в 'feature'. Когда новые изменения извлекаются в «master», git merge master внутри «feature» вводит новые файлы (и они автоматически размещаются в VSCode, который является IDE, которую я использую).

Что я делаю дальше, так это разархивирую все эти файлы. В основном их игнорируют. Добавляйте и сохраняйте только те файлы, которые я изменяю. Нажмите «функцию» в исходное / удаленное репо, создайте запрос на извлечение. Когда запрос принят и коммит слит с основной веткой, удалите «функцию» локально и удаленно. Вытяните изменения в «master» local и создайте новую ветку для работы над новой функцией. Эта новая ветвь не будет иметь кучу неподготовленных файлов.

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

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