Как мне отменить коммит SVN?


303

Я нашел различные примеры того, как отменить коммит SVN, как

svn merge -r [current_version]:[previous_version] [repository_url]

или

svn merge -c -[R] .

Но ни один из них, кажется, не работает. Я попробовал эти команды и проверил файлы, которые были изменены вручную.

Как мне отменить коммит с ревизией № 1944? Как я могу проверить, что возврат был сделан (не смотря в фактическом файле, чтобы изменения были отменены)?


16
Ты никогда не принимал ответ, потому что никто из них не работал?
2rs2ts

4
Если вы хотите буквальный ответ, используйте «svn merge -c -1944». Чтобы проверить, сработало ли это: "svn diff"
Джон Сэмпсон,



Что, если дело, у меня 1943 (хороший коммит), затем 1944 (плохой коммит), затем 1945 (хороший коммит), затем 1946 (хороший коммит). Теперь я хочу удалить только 1944 (плохой коммит) и сохранить все ревизии после 1944 года, то есть мне нужен результат, подобный 1943, 1945, 1946 (удалить только 1944) из всех этих ревизий, что мне делать ??
Bhavin_m

Ответы:


448

Оба примера должны работать, но

svn merge -r UPREV:LOWREV . отменить диапазон

svn merge -c -REV . отменить одну ревизию

в этом синтаксисе - если текущим каталогом является WC и (как это должно быть сделано после каждого слияния) вы передадите результаты

Хотите посмотреть логи?


9
@dwjohnston - да, слияния всегда выполняются в WC, и это не задача на стороне сервера
Lazy Badger

14
svn: Merge source required, Нет кости.
2rs2ts

27
@ 2rs2ts похоже, что вы забыли конечную точку, чтобы обозначить «сделать это в текущем каталоге».
Далин

14
Вы также можете сделать несколько одиночных svn merge -c -42587,-42589 .
коммитов

1
@ahnbizcad - ревизия (сингл), которую вы хотите отменить
Lazy Badger

130

Если вы используете клиент TortoiseSVN , это легко сделать через диалог Показать журнал .


5
Это, безусловно, самый простой способ сделать это
Маркку К.

5
Это устарело. Больше не существует контекстного меню, доступного для клиента в текущей версии.
user1789573

19
Какой? TortoiseSVN - это контекстное меню, а также диалоговые окна, которые оно порождает. Что вы подразумеваете под "там больше нет контекстного меню"? Там, безусловно, есть!
Бен

@Ben Я думаю, что user1789573 немного запутался из-за явного упоминания «Контекстного меню» в руководстве, на которое есть ссылка в ответе.
Том Катулло

2
Если вы видите это позже, это (все еще) там. На экране журнала регистрации щелкните правой кнопкой мыши редакцию, и появится опция «Вернуться к этой редакции». Это в TortoiseSVN 1.9.4 Build 27285. Я только что использовал его и могу сказать, что он работает просто отлично.
Брюс Ван Хорн

65

svn merge -r 1944:1943 .следует отменить изменения r1944 в вашей рабочей копии. Затем вы можете просмотреть изменения в вашей рабочей копии (с помощью diff), но вам нужно будет зафиксировать их, чтобы применить возврат в хранилище.


4
Не работает, требуется источник слияния. Пробовал svn merge -r 1944:1943 .вместо этого, но ничего не изменилось.
Алекс

Продвинулся ли репозиторий с 1944 года? Если да, есть ли противоречивые изменения в тех же строках, что и изменения между r1943 и r1944?
onon15

Я нахожусь на пересмотре 1945 года, и, кажется, нет конфликта. Ни то, svn statusни другое svn diffничего не дает.
Алекс

7
Ошибка:svn: Try 'svn help' for more info svn: Merge source required
Алекс

5
Но, svn merge -r 1945:1943 .похоже, сработало. Я думаю, что понимаю: вам нужно объединить версию из «до» «плохого» коммита в ваш рабочий репозиторий. Это нормально, если вы хотите сделать простой «возврат» предыдущего коммита. Но что, если вы хотите отменить изменения, сделанные в версии 1900?
Алекс

45

Сначала верните рабочую копию в 1943 году.

> svn merge -c -1943 .

Во-вторых, проверьте, что должно быть совершено.

> svn status

В-третьих, зафиксируйте версию 1945.

> svn commit -m "Fix bad commit."

В-четвертых, посмотрите на новый журнал.

> svn log -l 4

------------------------------------------------------------------------
1945 | myname | 2015-04-20 19:20:51 -0700 (Mon, 20 Apr 2015) | 1 line

Fix bad commit.
------------------------------------------------------------------------
1944 | myname | 2015-04-20 19:09:58 -0700 (Mon, 20 Apr 2015) | 1 line

This is the bad commit that I made.
------------------------------------------------------------------------
1943 | myname | 2015-04-20 18:36:45 -0700 (Mon, 20 Apr 2015) | 1 line

This was a good commit.
------------------------------------------------------------------------

1
Что, если дело, у меня 1943 (хороший коммит), затем 1944 (плохой коммит), затем 1945 (хороший коммит), затем 1946 (хороший коммит). Теперь я хочу удалить только 1944 (плохой коммит) и сохранить все ревизии после 1944 года, то есть мне нужен результат, подобный 1943, 1945, 1946 (удалить только 1944) из всех этих ревизий, что мне делать ??
Bhavin_m

26

Невозможно «отменить» ревизию, но вы можете вернуть свою рабочую копию в версию 1943 и зафиксировать ее как версию 1945. Версии 1943 и 1945 будут идентичны, что эффективно отменит изменения.


18
Просто чтобы быть досадно точным, я бы прокомментировал, что, если у вас есть доступ администратора к хранилищу, вы можете «удалить». Это путем создания хранилища клонов до определенной ревизии с помощью svn dumpи затем svn load. Но, конечно, это не должно использоваться в нормальных условиях.
onon15

4
Я не хочу отменять коммит, я хочу создать новый номер коммита с инвертированным определенным коммитом. Множество говорит, что я проверил версию 1944 года, сделал коммит в 1945 году, который я хочу «вернуть». Тогда я хочу иметь версию 1946, файлы которой идентичны файлам в версии 1944. (За исключением, конечно, истории.) Но остается вопрос: как это сделать? Какие команды?
Алекс

//, @Alex, меня это тоже интересует, особенно чем-то аналогичным $ git revert. Мне было довольно сложно изучать SVN после того, как я так долго пользовался Git.
Натан Басанезе

10

Следующее сделает пробный прогон, как говорится. HEAD - текущая версия, PREV - предыдущая, затем путь к вашему файлу или подтвержденному элементу:

svn merge --dry-run -rHEAD:PREV https://example.com/svn/myproject/trunk

Если пробный запуск выглядит хорошо, запустите команду без --dry-run

Проверьте изменение в ревизии и повторите. Чтобы найти номера версий, попробуйте:

svn log

4
F=code.c
REV=123
svn diff -c $REV $F | patch -R -p0 \
    && svn commit -m "undid rev $REV" $F

Требует ли это, чтобы локальная копия отличалась от неверной ревизии?
Элиэзер Мирон


2

Хотя приведенные предложения могут работать для некоторых людей, в моем случае это не работает. При выполнении слияния пользователи, rev 1443которые обновляются до rev 1445, по-прежнему синхронизируют все измененные файлы, 1444даже если они равны 1443слиянию. Мне нужно, чтобы конечные пользователи вообще не видели обновления.

Если вы хотите полностью скрыть фиксацию, это можно сделать, создав новую ветку с правильной ревизией, а затем поменяв местами ветки. Единственное, вам нужно снять и заново добавить все блокировки.

copy -r 1443 file:///<your_branch> file:///<your_branch_at_correct_rev>
svn move file:///<your_branch> file:///<backup_branch>
svn move file:///<your_branch_at_correct_rev> file:///<your_branch>

Это сработало для меня, возможно, это будет полезно для кого-то еще там =)


2
svn merge -c -M PATH

Это спасло мою жизнь.

У меня была та же проблема, после возврата назад я также не видел старый код. После выполнения вышеуказанной команды я получил чистый код старой версии.


1

Я попробовал выше, ( svn merge), и вы правы, это делает Джек. тем не мение

svn update -r <revision> <target> [-R]

кажется, работает, но не постоянно (мой SVN просто показывает старую ревизию). Так что мне пришлось

mv <target> <target backup>
svn update <target>
mv <target backup> <target>
svn commit -m "Reverted commit on <target>" <target>

В моем конкретном случае моя цель interfaces/AngelInterface.php. Я внес изменения в файл, зафиксировал их, обновил компьютер сборки, запустил компилятор phpdoc и обнаружил, что мои изменения были пустой тратой времени. svn log interfaces/AngelInterface.phpпоказывает мое изменение как r22060 и предыдущий коммит в этом файле был r22059. Так что я могу svn update -r 22059 interfaces/AngelInterface.phpи в итоге получаю код, который снова был в -r22059. Затем :-

mv interfaces/AngelInterface.php interfaces/AngelInterface.php~
svn update interfaces/AngelInterface.php
mv interfaces/AngelInterface.php~ interfaces/AngelInterface.php
svn commit -m "reverted -r22060" interfaces/AngelInterface.php

В качестве альтернативы я мог бы сделать то же самое с каталогом, указав . -Rвместо него interfaces/AngelInterface.phpвсе вышеперечисленное.


1
Еще одна вещь, как уже было сказано, что вы не можете сделать, это удалить коммит из истории, как вы можете сделать это в git, взломав ссылки напрямую. Все, что вы можете сделать, это использовать репозиторий, чтобы изменить исходный код так, как вы его планируете, и зафиксировать это как изменение.
Сибаз

После дальнейшего изучения я вижу, что можно удалить коммит из истории, используя svnadmin, но вам настоятельно рекомендуется не делать этого. См stackoverflow.com/questions/5566327/...
sibaz

0

Если вы хотите полностью удалить коммиты из истории, вы также можете сделать дамп репо с определенной ревизией, а затем импортировать этот дамп. В частности:

svnrdump dump -r 1:<rev> <url> > filename.dump

Команда svnrdump выполняет ту же функцию, что и дамп svnadmin, но работает на удаленном репо.

Затем просто импортируйте файл дампа в ваш репозиторий. Это было проверено, чтобы хорошо работать на Beanstalk.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.