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

См. Дополнительную информацию об атрибутах git

Другие вопросы по тегам