Git Merge конфликта, чтобы всегда принимать новейший файл
Как я могу разрешить конфликт git ВСЕГДА, решив, взяв новейший файл (последняя измененная временная метка), полностью без запроса?
Я создаю синтаксис с git backend, и я никогда не хочу на самом деле объединять файл, просто переопределить все старые копии той, которая была отредактирована / удалена / добавлена последней.
Редактировать: с новым файлом, я имею в виду новейший коммит, содержащий этот файл.
2 ответа
Я придумал этот маленький драйвер слияния, который делает то, что я хочу. Для моей цели он жестко запрограммирован в ветке "master" и в "origin" remote. Я не знаю, как сделать эти части динамичными.
#!/usr/bin/env sh
if git merge-file -p -q "$2" "$1" "$3" > /dev/null;
then git merge-file "$2" "$1" "$3";
else
MINE=$(git log --format="%ct" --no-merges master -1);
THEIRS=$(git log --format="%ct" --no-merges origin/master -1);
if [ $MINE -gt $THEIRS ];
then git merge-file -q --ours "$2" "$1" "$3";
else git merge-file -q --theirs "$2" "$1" "$3";
fi
fi
Короче говоря, я ищу последний коммит с git-log, который не был слиянием, отформатированный как метка времени UNIX, затем я сравниваю их и запускаю пользовательское git-merge с eiter нашей или их версией.
В качестве небольшого бонуса он сначала проверяет, можно ли объединить файл без конфликта. Если это возможно, он объединяет оба файла.
Я думаю, вам придется написать свой собственный драйвер слияния для этого. Смотрите "git help gitattributes", разделы "Определение пользовательского драйвера слияния", чтобы узнать, как это сделать.
На основе ответа @Lilleman, который хорош, но имеет ошибку: если файл изменен на локальном мастере, который старше, чем origin/master, ожидаемым поведением является выбор origin/master, но если вы добавите фиксацию поверх локального мастера, он будет выберите локальную (более старую версию) файла. git log необходимо запустить с дополнительным аргументом, которым является путь к файлу.
здесь лучшая версия, включая имена веток переменных, это немного взломано, но работает
слияние
#!/bin/sh
cd `findup .git`
PATH=$PATH:$( dirname "${BASH_SOURCE[0]}" )
HEAD=`git rev-parse --abbrev-ref HEAD`
echo "* merge=newest" > .gitattributes
sed -ie '/merge "newest"/,+2d' .git/config
echo "[merge \"newest\"]" >> .git/config
echo -e "\tname = Merge by newest commit" >> .git/config
echo -e "\tdriver = git-merge-newest %O %A %B %L %P $HEAD $1" >> .git/config
git merge $1
sed -ie '/merge "newest"/,+2d' .git/config
rm .gitattributes
cd -
git-merge-новые
#!/bin/sh
if git merge-file -p -q "$2" "$1" "$3" > /dev/null;
then git merge-file "$2" "$1" "$3";
else
MINE=$(git log --format="%ct" --no-merges "$6" -1 $5);
THEIRS=$(git log --format="%ct" --no-merges "$7" -1 $5);
if [ $MINE -gt $THEIRS ]; then
git merge-file -q --ours "$2" "$1" "$3" >/dev/null
else
git merge-file -q --theirs "$2" "$1" "$3">/dev/null
fi
fi
Findup используется
#!/bin/sh
pwd="`pwd`"
start="$pwd"
while [ ! "$pwd" -ef .. ]; do
[ -e "$1" ] && echo -n "$pwd" && exit
cd .. || exit 1
pwd="`pwd`"
done
exit 1
Если кто-то пришел сюда в поисках решения, чтобы избежать разрешения конфликтов, возникающих из автоматически сгенерированных файлов, таких как
package-lock.json
,
pubspec.lock
,
*.pbxproj
, то вы можете создать
.gitattributes
файл, определяющий стратегию слияния
package-lock.json merge=union