Откат к старой фиксации с повторным повторением

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

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

Ответ 1

git revert должен принять одно коммит, так что ошибка жалуется, что вы даете ему список изменений, где он ожидает его. (Update: спасибо Jefromi за то, что, поскольку 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

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

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

# 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 делают это приятным и ясным, я думаю.

Ответ 2

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

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

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

(@{1} относится только к фиксации вашей ветки, указанной перед reset.)

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