Как навсегда предотвратить передачу определенной части файла в git?
Я клонировал удаленный репозиторий SVN с git -svn. Я изменил файл pom.xml в этом клонированном репо способом, который компилирует код. Эта настройка для меня исключительно. Таким образом, я не хочу возвращать изменения на дистанционное репо.
Есть ли способ предотвратить эту (частичную) смену файла на передачу в репо? Я знаю, что я мог бы использовать личную ветвь, но это означало бы определенные слияния накладных расходов. Существуют ли другие способы?
Я рассмотрел этот question и этот один, но они предназначены для довольно временных изменения.
Обновление: я также знаю возможности .gitignore, но это означало бы полностью исключить файл.
Ответы
Ответ 1
EDIT: То, что вы просите, невозможно, я не видел "частичную" часть.
Я знаю, что вы можете фиксировать только часть файлов, но вы не можете игнорировать часть файла.
Вам нужно будет использовать трюк индекса обновления, чтобы избежать его в "статусе", и вам нужно будет хранить этот файл каждый раз, когда вы будете переустанавливать/слить с удаленного, а затем разблокировать изменения и игнорировать вашу модификацию с помощью update- индекс.
Я не знаю, можете ли вы создать псевдоним git для последовательности команд git, поэтому с помощью одной команды вы можете сделать все эти 3 команды, чтобы избежать проблем с
используйте файл .gitignore и не нажимайте его на дистанционное репо: Игнорировать сам файл .gitignore
в .gitignore, вы должны иметь
.gitignore
path/to/pom.xml
a .gitignore файл может находиться в корне рабочего дерева или в любом подкаталоге, который вы хотите/нуждаетесь
Ответ 2
Там может быть возможность с фильтрами. Но это нужно изучить больше.
Начальная точка: выполните смазывание/очистить этот фильтр:
git config --global filter.versionUpdate.smudge 'sed "s/<version>14.5.0<\/version>/<version>14.5.FEATURE-15<\/version>/"'
git config --global filter.versionUpdate.clean 'sed "s/<version>FEATURE-15<\/version>/<version>14.5.0<\/version>/"'
Таким образом, при сопоставлении файл всегда будет таким же, как и фильтр.
Проблема: по-прежнему требуется расследование, как найти отфильтрованные файлы. Это не так заметно в рабочем каталоге.
![Фильтр очистки Smudge]()
Ответ 3
Один из общих способов поделиться этим типом файла конфигурации:
- зафиксировать файл шаблона (например,
pom.xml.template
)
- игнорировать сам файл (например, добавить
pom.xml
в файл .gitignore
)
- каждый пользователь может настроить этот файл в соответствии со своими потребностями
Вот несколько способов реализовать шаг 3.
- попросите пользователя вручную отредактировать, скопировать файл шаблона и отредактировать его
- есть некоторый скрипт, который применяет подстановку к файлу шаблона и записывает вывод в ожидаемую цель
Ответ 4
Может быть проще решить вашу проблему вне git.
Вы можете определить свойство со значением по умолчанию в pom.xml,
который каждый использует.
А для вашей эксклюзивной настройки вы просто переопределяете свойство в ${user.home}/.m2/settings.xml
или в командной строке Maven, используя -Dproperty=value
.
Или аналогичным образом вы можете создать другой профиль и активировать его на основе переменной среды, которую вы экспортируете, скажем, в ~/.bashrc.
Для git-решения я выполнил то, что вы хотите, с некоторой дисциплиной в правильном соблюдении рабочего процесса:
- Внесите изменения, относящиеся к настройке, в pom.xml (или другие файлы).
- Зафиксируйте изменения в git (только локально). В заголовке/сообщении коммита укажите, что изменения предназначены только для локального использования, например "ТОЛЬКО ЛОКАЛЬНО. НЕ ПОЛЬЗУЙТЕСЬ: остальная часть заголовка".
- Вытащить изменения из SVN, сделать локальные коммиты Git и т.д.
- Как только пришло время отменить ваши изменения обратно в SVN, сделайте
git svn rebase
получать новые коммиты из SVN, разрешать конфликты.
git rebase -i svn/trunk
(или какова ваша удаленная ветвь svn) (это запустит интерактивный перебаз всех ваших локальных изменений поверх SVN)
- В интерактивном редакторе задач rebase переместите свой локальный коммит в нижнюю часть.
- Сохраните задачу и выйдите из редактора задач.
- Устраните любые конфликты (их не должно быть, если вы не коснулись той же части вашего pom.xml (или другого локального файла) в других локальных коммитах).
- Запустите
git svn dcommit --dry-run @~1
(или git svn dcommit --dry-run HEAD~1
в старом git), чтобы увидеть, что будет отправлено в репозиторий SVN; убедитесь, что ваши локальные коммиты отсутствуют в списке.
- Запустите
git svn dcommit @~1
(или git svn dcommit HEAD~1
), чтобы, наконец, отправить изменения в репозиторий SVN.
git svn rebase
чтобы получать новые коммиты из SVN.
Это может звучать сложно, но это довольно просто, когда вы привыкнете к этому. По сути, у вас есть одна (или более) локальная фиксация, которую вы никогда не отправляете в SVN. У меня не было ошибочно выдвинутого коммита более года, используя этот рабочий процесс с несколькими коммитами и репозиториями. Это довольно полезно, например, для некоторых локальных изменений только для отладки (хотя для этого лучше ввести переменную окружения или какой-то файл настроек).
Кроме того, это может быть улучшено с помощью ловушки pre-dcommit в git, который будет гарантировать, что изменения только локальные не будут dcommit'ed. К сожалению, я не вижу стандартного хука git-svn для этого, но можно использовать git-svn-hooks для их реализации.
Ответ 5
Это звучит для меня как веский аргумент в пользу ловушки перед фиксацией. В вашей папке .git у вас должна быть папка hooks. Там могут быть некоторые образцы, но они игнорируются, поскольку имеют расширение .sample. Если вы добавите файл с именем "pre-commit" (без расширения), содержащий приведенный ниже скрипт, скрипт будет запускаться каждый раз, когда вы делаете коммит. Не забудьте сделать сценарий исполняемым, запустив "chmod ug + x pre-commit".
Я добавил несколько комментариев, объясняющих, что делает каждая строка, но, по сути, как бы вы ее использовали, вы бы поместили "#start" над кодом, который вы не хотите включать в ваши коммиты git, а затем "#end" под этим кодом. Вы можете использовать разные стартовые и конечные флаги в команде sed, просто убедитесь, что вы используете синтаксис комментариев для любого языка, на котором вы разрабатываете, чтобы компилятор их игнорировал. Когда вы в конце концов выполните коммит, произойдет следующее:
- Код посередине (включая флаги #start и #end) будет удален
- Файл будет зафиксирован без кода и флажков
- Затем код и флаги будут возвращены в вашу локальную копию файла
Поскольку все это содержится в хуке перед фиксацией, это будет происходить автоматически каждый раз, когда вы фиксируете.
перед фиксацией
#!/usr/bin/env bash
echo "Running pre-commit hook..."
set -e
export PATH=$PATH:/usr/local/bin
exit_status=0
echo "Removing supercomments..."
# Get a list of files part of this commit
files=$(git diff --cached --name-status)
# Loop through each file
for f in $(echo $files | awk '{ print $2}')
do
# Create a temp copy of the file
cp ${f} ${f}.temp
# Remove all chunks between '#start' and '#end'
sed -i '/#start/,/#end/d' ${f}
# Add the file with chunks removed
git add ${f}
# Replace file with temp file containing code you didn't want to comm
it
cp ${f}.temp ${f}
done
echo "Hook completed!"
exit $exit_status
Пример использования:
test.txt
This is a file
It really just a test file
#start
This code is only relevant to me
When I eventually commit this file...
...please don't inclue all of this!
#end
This part of the file is important,
make sure it included in my next commit.
добавить & передайте test.txt:
git add test.txt
#
git commit -m "A great commit message."
# Running pre-commit hook...
# Removing supercomments...
# Hook completed!
# [master commit_id_1234] A great commit message.
test.txt (в commit_id_1234)
This is a file
It really just a test file
This part of the file is important,
make sure it included in my next commit.
test.txt (локальная копия после фиксации)
This is a file
It really just a test file
#start
This code is only relevant to me
When I eventually commit this file...
...please don't inclue all of this!
#end
This part of the file is important,
make sure it included in my next commit.
Примечание:
Есть несколько нюансов в вашем вопросе для рассмотрения. Похоже, у вас есть набор кода, который вы хотите иметь в своих файлах, но только при локальной компиляции (я предполагаю, что вы в основном разрабатываете и тестируете свой код локально), но затем вы хотите иметь возможность зафиксировать этот код разработки и автоматически удалить ваш "только локально релевантный код" перед фиксацией. Хотя описанный выше хук должен делать именно это, имейте в виду, что часть "only-local-релевантного кода" не является версионной, поскольку она никогда не попадает в ваш удаленный репозиторий, когда вы в конечном итоге отправляете. Это может быть очевидно, но просто убедитесь, что вы в порядке с этим. Если что-то случится с вашей локальной копией, весь этот код, даже если он имеет отношение только к вам, может быть утерян и не может быть восстановлен путем простого клонирования репозитория.
Ответ 6
Хорошие идеи уже предложены. Prehooks кажется наиболее подходящим, пожалуй. Некоторые другие возможности для рассмотрения могут быть:
- Форк репо и зафиксировать все изменения
- Зафиксируйте отдельную ветку в том же репо и зафиксируйте
- Есть локальный филиал только ваших личных различий, которые вы выбираете, когда проверяете, и проверяете перед регистрацией?
- Применить файлы исправлений - снова, которые могут быть отменены перед проверкой (хотя проблематично)