Вы можете объединить свою восходящую ветку со своей dev
веткой с помощью специального драйвера слияния «keepTheirs» :
см. « « git merge -s theirs
»Необходимо, но я знаю, что его не существует ».
В вашем случае .gitattributes
потребуется только один и такой keepTheirs
сценарий:
mv -f $3 $2
exit 0
git merge --strategy=theirs
Симулятор # 1
Отображается как слияние с восходящим потоком в качестве первого родителя.
Джефроми упоминает (в комментариях) merge -s ours
, объединив вашу работу в восходящем потоке (или во временной ветке, начиная с восходящего потока), а затем переместив вашу ветку вперед к результату этого слияния:
git checkout -b tmp origin/upstream
git merge -s ours downstream # ignoring all changes from downstream
git checkout downstream
git merge tmp # fast-forward to tmp HEAD
git branch -D tmp # deleting tmp
Это дает преимущество записи вышестоящего предка в качестве первого родителя, так что слияние означает «поглощение этой устаревшей тематической ветки», а не «уничтожение этой тематической ветки и замена ее вышестоящей» .
(Изменить 2011):
OP сообщил об этом рабочем процессе в этом сообщении в блоге :
Зачем мне это снова?
Пока мое репо не имело ничего общего с общедоступной версией, все было в порядке, но поскольку теперь я хотел бы иметь возможность сотрудничать по WIP с другими членами команды и внешними участниками, я хочу убедиться, что мои общедоступные ветки надежный для других, чтобы разветвляться и извлекать из него, т.е. больше не нужно переустанавливать и сбрасывать вещи, которые я помещал в удаленную резервную копию, поскольку теперь он находится на GitHub и общедоступен.
Так что мне остается только решить, как мне поступить.
В 99% случаев моя копия попадает в основной сервер восходящего потока, поэтому я хочу работать со своим мастером и большую часть времени продвигаться в восходящий поток.
Но время от времени то, что у меня есть wip
, становится недействительным из-за того, что идет вверх по течению, и я откажусь от некоторой части своего wip
.
На этом этапе я хочу вернуть своего мастера обратно в синхронизацию с восходящим потоком, но не уничтожать какие-либо точки фиксации на моем публично выдвинутом мастере. Т.е. я хочу слияние с восходящим потоком, которое закончится набором изменений, который сделает мою копию идентичной исходной .
И вот что git merge --strategy=theirs
надо делать.
git merge --strategy=theirs
Симулятор # 2
Отображается как слияние с нашим в качестве первого родителя.
(предложено jcwenger )
git checkout -b tmp upstream
git merge -s ours thebranch # ignoring all changes from downstream
git checkout downstream
git merge --squash tmp # apply changes from tmp but not as merge.
git rev-parse upstream > .git/MERGE_HEAD #record upstream 2nd merge head
git commit -m "rebaselined thebranch from upstream" # make the commit.
git branch -D tmp # deleting tmp
git merge --strategy=theirs
Симулятор # 3
В этом сообщении в блоге упоминается :
git merge -s ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply -R --index
git commit -F .git/COMMIT_EDITMSG --amend
иногда вы действительно хотите это сделать, и не потому, что в вашей истории есть «чушь», а, возможно, потому, что вы хотите изменить базовый план для разработки в публичном репозитории, где следует избегать перенастройки .
git merge --strategy=theirs
Симулятор # 4
(тот же пост в блоге)
В качестве альтернативы, если вы хотите поддерживать быструю пересылку локальных ветвей восходящего потока, потенциальный компромисс заключается в том, чтобы работать с пониманием того, что для sid / unstable ветвь восходящего потока может время от времени сбрасываться / перемещаться (на основе событий, которые в конечном итоге отсутствуют вашего контроля на стороне восходящего проекта).
Это не имеет большого значения, и работа с этим предположением означает, что легко поддерживать локальную ветвь восходящего потока в состоянии, при котором она принимает только быстрые обновления.
git branch -m upstream-unstable upstream-unstable-save
git branch upstream-unstable upstream-remote/master
git merge -s ours upstream-unstable
git diff --binary ref-to-be-merged | git apply -R --index --exclude="debian/*"
git commit -F .git/COMMIT_EDITMSG --amend
git merge --strategy=theirs
Симулятор # 5
(предложено Бараком А. Перлмуттером ):
git checkout MINE
git merge --no-commit -s ours HERS
git rm -rf .
git checkout HERS -- .
git checkout MINE -- debian # or whatever, as appropriate
git gui # edit commit message & click commit button
git merge --strategy=theirs
Симулятор # 6
(предложено все тем же Майклом Гебецройтером ):
Вмешался Майкл Гебетсройтер, заявив, что я «жульничал»;) и предложил другое решение с низкоуровневыми командами сантехники:
(это не было бы git, если бы это было невозможно с командами git only, все в git с diff / patch / apply не является настоящим решением;).
# get the contents of another branch
git read-tree -u --reset <ID>
# selectivly merge subdirectories
# e.g superseed upstream source with that from another branch
git merge -s ours --no-commit other_upstream
git read-tree --reset -u other_upstream # or use --prefix=foo/
git checkout HEAD -- debian/
git checkout HEAD -- .gitignore
git commit -m 'superseed upstream source' -a
git merge --strategy=theirs
Симулятор # 7
Необходимые шаги можно описать так:
- Замените свое рабочее дерево на восходящее
- Применить изменения к индексу
- Добавить восходящий поток в качестве второго родителя
- Зафиксировать
Команда git read-tree
перезаписывает индекс другим деревом, выполняя второй шаг , и имеет флаги для обновления рабочего дерева, выполняя первый шаг . При фиксации git использует SHA1 в .git / MERGE_HEAD в качестве второго родителя, поэтому мы можем заполнить его для создания фиксации слияния. Следовательно, этого можно добиться с помощью:
git read-tree -u --reset upstream # update files and stage changes
git rev-parse upstream > .git/MERGE_HEAD # setup merge commit
git commit -m "Merge branch 'upstream' into mine" # commit