Временно уберите незафиксированные изменения в Subversion (a la " git-stash")
при программировании программного обеспечения, хранящегося в репозитории Subversion, я часто изменяю некоторые файлы, а затем замечаю, что я хотел бы сделать некоторые подготовительные изменения для своей основной работы. Например, при реализации новой функциональности я замечаю некоторый рефакторинг, который может мне помочь.
чтобы не смешивать два несвязанных изменения, в этих случаях я хотел бы "убрать" мои изменения, т. е. вернуться к версии репозитория, сделать некоторые другие изменения, зафиксировать их, а затем "вернуть" мои изменения.
git-stash позволяет сделать именно это. Есть ли способ сделать это с помощью Subversion, либо напрямую, либо с помощью какого-либо плагина или скрипта. Плагины Eclipse также будут в порядке.
15 ответов:
когда у меня есть незафиксированные изменения одной из задач моей рабочей копии и мне нужно переключиться на другую задачу, я делаю одну из двух вещей:
проверить новую рабочую копию для второй задачи.
или
запустить ветку:
workingcopy$ svn copy CURRENT_URL_OF_WORKING_COPY SOME_BRANCH workingcopy$ svn switch SOME_BRANCH workingcopy$ svn commit -m "work in progress" workingcoyp$ svn switch WHATEVER_I_WAS_WORKING_ON_BEFOREУ меня есть несколько скриптов, которые помогают автоматизировать это.
этот блог советует использовать diff и патч.
git stashпримерно становитсяsvn diff > patch_name.patch; svn revert -R .git stash applyстановитсяpatch -p0 < patch_name.patchобратите внимание, что это не скрывает изменения метаданных или (я думаю) каталог создает/удаляет. (Да, svn отслеживает их отдельно от содержимого каталога, в отличие от git.)
вы можете сохранить ваши текущие изменения с
svn diffв файл патча, затем верните свою рабочую копию:svn diff > stash.patch svn revert -R .после того, как вы реализовали свою подготовительную функцию, вы можете применить свой патч с помощью утилиты patch:
patch < stash.patchкак уже отметили, это не будет работать с
svn:propertiesи операции с деревом (добавление, удаление, переименование файлов и каталогов).двоичные файлы также могут дать проблемы, я не знаю, как патч (или TortoiseSVN в этом случае справиться с ними.)
самый простой способ-использовать временную ветвь, например:
$ svn copy ^/trunk ^/branches/tempbranch $ svn switch ^/branches/tempbranch $ svn commit -m "Stashed" $ svn switch ^/trunk $ ... hack away in trunk ... $ svn commit -m "..." $ svn merge ^/branches/tempbranch . $ svn rm ^/branches/tempbranch $ ... continue hackingЭто может (и, вероятно, должно) быть помещено в скрипт, если это делается на более регулярной основе.
по состоянию на 2018-04-13 (Subversion 1.10.0), у вас есть экспериментальные
svn shelveкоманда. (TortoiseSVN поддерживает команду)В настоящее время это не что иное, как помощник, чтобы сохранить патч и применить его обратно, поэтому он имеет те же ограничения, что и
svn diff+patch(т. е. не может обрабатывать двоичные файлы и переименовывает). (Edit:похоже, что поддержка двоичных файлов идет в следующей версии)$ svn shelve --help x-shelve (shelve): Put a local change aside, as if putting it on a shelf. usage: 1. x-shelve [--keep-local] NAME [PATH...] 2. x-shelve --delete NAME 3. x-shelve --list 1. Save the local change in the given PATHs to a patch file, and revert that change from the WC unless '--keep-local' is given. If a log message is given with '-m' or '-F', include it at the beginning of the patch file. 2. Delete the shelved change NAME. (A backup is kept, named with a '.bak' extension.) 3. List shelved changes. Include the first line of any log message and some details about the contents of the change, unless '-q' is given. The kinds of change you can shelve are those supported by 'svn diff' and 'svn patch'. The following are currently NOT supported: mergeinfo changes, copies, moves, mkdir, rmdir, 'binary' content, uncommittable states To bring back a shelved change, use 'svn x-unshelve NAME'. Shelved changes are stored in <WC>/.svn/shelves/ The shelving feature is EXPERIMENTAL. This command is likely to change in the next release, and there is no promise of backward compatibility. Valid options: --delete : delete the shelved patch --list : list shelved patches -q [--quiet] : print nothing, or only summary information --dry-run : try operation but make no changes --keep-local : keep path in working copy (...) $ svn unshelve --help x-unshelve (unshelve): Bring a shelved change back to a local change in the WC. usage: 1. x-unshelve [--keep-shelved] [NAME] 2. x-unshelve --list 1. Apply the shelved change NAME to the working copy. Delete the patch unless the '--keep-shelved' option is given. (A backup is kept, named with a '.bak' extension.) NAME defaults to the most recent shelved change. 2. List shelved changes. Include the first line of any log message and some details about the contents of the change, unless '-q' is given. Any conflict between the change being unshelved and a change already in the WC is handled the same way as by 'svn patch', creating a 'reject' file. The shelving feature is EXPERIMENTAL. This command is likely to change in the next release, and there is no promise of backward compatibility. Valid options: --keep-shelved : do not delete the shelved patch --list : list shelved patches -q [--quiet] : print nothing, or only summary information --dry-run : try operation but make no changes (...)
Я не знаю простого способа сделать это с помощью только svn. Честно говоря, я бы посоветовал использовать
git-svnчтобы сделать РЕПО git, которое действует как рабочая копия svn, и просто используяgit stashС, что. Просто заменитеgit pullСgit svn rebaseиgit pushСgit svn dcommitи вы можете фактически сохранить 90% вашего рабочего процесса git и все еще разговаривать с сервером svn.
есть небольшой скрипт Python 2 под названием
svn-stashдоступно под GPL 3:https://github.com/frankcortes/svn-stash .Он работает как
svn diff/patchупомянутые решения и предложения подталкивают и выталкивают изменения в качестве различий в некотором локальном каталоге. К сожалению, тайники не могут быть названы, и только последний может быть выскочил (ну да, это стек, но нет реальной причины для такого ограничения.) Но тогда вы всегда можете построить недостающие функции в источник.Он написан для *ix, но после замены каждого " / " на
os.sepОн прекрасно работает и под Windows.если вы используете SVN 1.7 или выше, вам нужно изменить
is_a_current_stash(): удалить строкуif ".svn" in os.listdir(CURRENT_DIR):, так как есть только один верхний уровень .svn subdir в 1.7 WC.
вы можете сделать это легко, используя Intellij IDEA -Отложить Изменения
другой вариант-скопировать текущую проверку в новый каталог и отменить все изменения. таким образом, вы сэкономите хлопоты по созданию временной ветки на вашем сервере-ведь stashing-это локальная операция, которую не все должны видеть и могут делать довольно часто.
после фиксации исправления вы можете обновить свою основную рабочую копию и удалить свою "область хранения"
Я также хотел эту функцию. В настоящее время я использую TortoiseSVN.
Я не нашел жесткого решения, кроме как экспортировать дерево, вернуться в репозиторий внести свои изменения и зафиксировать, а затем сравнить изменения из экспортированного дерева обратно в мой каталог с исходным кодом, используя инструмент, подобный Beyond Compare.
или другим решением может быть ветвление от головы до другого каталога, внесение изменений и фиксация. Когда вы будете готовы объединить их в ваша другая рабочая копия, сделайте обновление и объедините свои изменения.
Я всегда держу вторую проверку, которую я называю "trunk_clean". Всякий раз, когда мне нужно сделать быстрое, изолированное изменение, связанное с тем, что я делаю, я просто совершаю эту проверку.
ветвления и исправления идеи выше велики, но они не работают хорошо для меня. Я использую визуальный инструмент diff, так что работает
git diffне создает текстовые патчи. Наша система сборки раскручивает новую среду каждый раз, когда создается ветка, поэтому создание временных ветвей "тайника" будет беспорядочным.вместо этого, я написал маленький shell-скрипт, который копирует файл в каталог "полки", добавляет метку времени, и отменяет изменения. Это не так надежно, как решения выше, но это также позволяет избежать некоторых ловушек, с которыми я столкнулся.
на основе ответа Уолтера я создал следующие псевдонимы в моем файле bashrc:
alias svn.stash='read -p "saving local changes in raq.patch. Existing stash in raq.patch will be overwritten. Continue?[y/N]" && [[ $REPLY =~ ^[yY] ]] && rm -f raq.patch && svn diff > raq.patch && svn revert -R .' alias svn.stash.apply='patch -p0 < raq.patch; rm -f raq.patch'эти псевдонимы гораздо проще использовать и запоминать.
использование:
svn.тайник, чтобы спрятать изменения и svn.припрятывать.применить применить заначку.
использование:
svn cp --parents . ^/trash-stash/my-stashон создаст ветвь из текущего местоположения и текущей ревизии, а затем зафиксирует изменения в рабочей копии в этой ветви без переключения на нее.
использование: копирование SRC[@REV]... DST
SRC и DST могут быть либо рабочей копией (WC) путь или URL:
WC -> URL: immediately commit a copy of WC to URLобратите внимание, что изменения в рабочей копии не будут автоматически возвращены (
cpэто просто копирование изменения в новой ветке), и вы должны вернуть их вручную.чтобы восстановить изменения, вы можете просто объединить изменения из вновь созданной ветви в рабочую копию.
svn merge --ignore-ancestry ^/trash-stash/my-stash -c <commited revision>
--ignore-ancestryиспользуется для того, чтобы не обновлять информацию о слиянии в рабочей копии.использование:
svn ls -v ^/trash-stash/чтобы увидеть, что у вас есть в stash path. Зафиксированные изменения также печатаются.
Если вам больше не нужен тайник, просто запустите:
svn rm ^/trash-stash/my-stashэтот решение лучше, чем использование патча в том, что если новые изменения в рабочей копии или в текущей ветке конфликтуют с изменениями в тайнике, вы можете разрешить конфликты с помощью средств svn, тогда как
patchв некоторых случаях просто не удастся или даже применить патч неправильно.
в моей практике я использую
git initсоздать репозиторий Git вtrunkкаталог моего репозитория Subversion, а затем я добавляю*.gitдля отсосов игнорировать шаблоны.после изменения некоторых файлов, если я хочу продолжить свою работу с основной линией Subversion, я просто использую
git stashприпрятать мою работу. После фиксации в репозитории Subversion я используюgit stash popдля восстановления моих модификаций.
Comments