Откат к старому коммиту с помощью многократного возврата - PullRequest
11 голосов
/ 17 января 2011

Я хочу откатиться до коммита, используя git revert, чтобы я мог сохранить историю. Есть ли более простой способ сделать это, чем запускать git revert для каждого хэша коммита, который я хочу вернуть? Есть ли более быстрый способ вернуться от определенного коммита до хэша другого коммита?

На странице руководства они утверждают, что вы можете сделать что-то подобное git revert -n master~5..master~2, но когда я пытаюсь это сделать, я получаю эту ошибку: fatal: Cannot find 'master~5..master~2'

Ответы [ 2 ]

21 голосов
/ 17 января 2011

git revert должен принять один коммит, так что ошибка жалуется на то, что вы даете ему список ревизий там, где его ожидают. (Обновление: спасибо Джефроми за указание на то, что начиная с 1.7.2, git revert фактически может принимать несколько коммитов.) Ниже я предложу три возможных варианта действий:

Создание нескольких фиксаций возврата

Я не уверен, что вы можете сделать это в одной команде, но если вы знаете, что db0bc - это последний хороший коммит (т.е. вы хотите отменить каждый коммит после этого), а история линейна, вы можете сделать :

for s in $(git rev-list --reverse db0bc..)
do
    git revert --no-edit $s
done

Возвращаясь прямо к старому состоянию, но все еще на одной ветке

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

# Check that "git status" is clean:
git status

# Set the index (staging area) to be as it was at commit db0bc:
git read-tree db0bc

# Create a commit based on that index:
git commit -m "Going back to the state at commit db0bc"

# Your working tree will still be as it was when you started, so
# you'll want to reset that to the new commit:
git reset --hard

Создать новую ветку для старых коммитов

Если вы единственный человек, работающий над проектом, или вы еще не нажали master, или вы знаете, что сброс основной ветки не вызовет проблем, вы можете выбрать альтернативную тактику и создать новую ветку. в вашей текущей позиции и затем сбросьте мастер обратно, как хорошо описано на странице отмены github . Короче можно сделать:

# Make sure you're on master:
git checkout master

# Check that "git status" is clean, since later you'll be using "git reset --hard":
git status

# Create a new branch based on your current HEAD:
git branch unwanted-work

# Reset master back to the last good commit:
git reset --hard db0bc

Диаграммы на этой странице github делают это красивым и ясным, я думаю.

9 голосов
/ 17 января 2011

ИМХО самый естественный подход - это сделать (при условии, что у вас есть чистая рабочая копия):

git reset --hard $lastnicecommit; git merge -s ours @{1}

, а затем git commit --amend, чтобы добавить описание.(В более новых версиях git git-merge уже можно указывать описание.)

(@{1} просто ссылается на коммит, на который ветка указала перед сбросом.)

Это делаетперемотка вперед и поэтому полностью документирует историю.Тем не менее, изменения, внесенные в коммиты, начиная с $lastnicecommit, не вносят никаких изменений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...