Сброс пульта до определенного коммита

709

Я хочу отменить все изменения, сделанные после коммита <commit-hash>. Так я и сделал:

git reset --hard <commit-hash>

Теперь я хочу сделать то же самое с моим пультом. Как я могу это сделать? Я сделал некоторые коммиты (и подтолкнул) после, <commit-hash>и я просто хочу отказаться от них всех. Есть только что - то пошло ужасно неправильно в пути , и я не хочу , чтобы сделать его хуже , чем это уже. ; (

Я в принципе хочу , чтобы перемотать мой origin/masterTo<commit-hash>

nacho4d
источник
3
Вы уверены, что ваши origin/masterпользователи не тянули и не давили? Изменение истории общедоступного (то есть нелокального) хранилища - это то, чего вы хотите избегать всегда.
Vindia
Возможный дубликат Как отменить несколько коммитов git?
Майкл Фрейдгейм,

Ответы:

1252

Предполагая, что ваша ветка вызывается masterкак здесь, так и удаленно, и что ваш удаленный вызывается, originвы можете сделать:

 git reset --hard <commit-hash>
 git push -f origin master

Однако вам следует избегать этого, если кто-то еще работает с вашим удаленным репозиторием и извлек ваши изменения. В этом случае было бы лучше отменить коммиты, которые вам не нужны, а затем нажать как обычно.

Обновление: вы объяснили ниже, что другие люди извлекли изменения, которые вы выдвинули, поэтому лучше создать новый коммит, который отменит все эти изменения . В этом ответе от Якуба Наребски есть хорошее объяснение ваших возможностей сделать это . Какой из них наиболее удобен, зависит от того, сколько коммитов вы хотите вернуть, и какой метод имеет для вас наибольшее значение.

Поскольку из вашего вопроса ясно, что вы уже использовали git reset --hardдля сброса masterветки, вам может потребоваться начать с использования, git reset --hard ORIG_HEADчтобы переместить ветку туда, где она была раньше. (Как всегда git reset --hard, убедитесь, что git statusон чистый, что вы находитесь на правильной ветке и что вы знаете, git reflogкак инструмент для восстановления явно потерянных коммитов.) Вы также должны проверить, ORIG_HEADуказывает ли правильный коммит, с помощью git show ORIG_HEAD.

Поиск проблемы:

Если вы получаете сообщение типа " ! [Удаленный отклонен] a60f7d85 -> master (обработчик предварительного получения отклонен) "

тогда вы должны разрешить переписывание истории ветки для конкретной ветки. Например, в BitBucket говорится: «Переписывание истории ветвей запрещено». Есть флажок с именем, Allow rewriting branch historyкоторый вы должны проверить.

Марк Лонгэйр
источник
21
Опасная опасность: этот сброс предполагает, что соответствующая ( отслеживающая ) ветвь в настоящее время извлечена, и нет никаких незафиксированных изменений, которые вы хотели бы сохранить. Используйте git update-refвместоreset --hard ; это позволит вам сделать то же самое, не имея рабочего дерева / проверенной ветки
sehe
3
Понимаю. Это было выдвинуто и изменено другими. Так что я должен использовать, revert но допустим, я хочу отменить последние 4 коммита, так что я должен сделать git revert comit1; git push; git revert comit2; git push; ...или просто git revert commit4; git push?
nacho4d
1
@ nacho4d: вам не нужно нажимать после каждого возврата - есть хорошее описание того, что делать в этом ответе от Якуба Наребски . Вам нужно отменить каждый коммит в обратном порядке - просто git revert commit4создание создает новый коммит, который отменяет только те изменения, которые были внесены в него commit4. Тем не менее, в ответе, на который я ссылаюсь, вы можете свернуть их в один коммит.
Марк Лонгэйр
1
@ Марк я уже запустил, git reset --hardно я удалил свой локальный и снова вытащил из источника, так что git revert ...теперь я могу сомневаться: мне нужно отменить каждый коммит и нажать (один за другим) или просто отменить первый коммит после только правильно совершить?
nacho4d
1
@sehe: это трудно использовать, потому что вам нужно использовать полное имя ссылки, и поэтому людям легко засорять свой .gitкаталог ссылками, которые они не собирались создавать. Я был неправ, говоря, что нет никаких проверок безопасности. Вы можете найти классификацию команд "plumbing" и "porcelain" на странице руководства git .
Марк Лонгэйр
123

Используйте другие ответы, если вы не против потерять локальные изменения. Этот метод все еще может разрушить ваш пульт, если вы выберете неверный коммит хеш для возврата.

Если вы просто хотите, чтобы удаленное соответствие было зафиксировано в любом месте вашего локального репо:

  1. Есть не делать каких - либо переустановку.
  2. Используйте, git logчтобы найти коммит, на котором вы хотите быть удаленным. git log -pчтобы увидеть изменения или git log --graph --all --oneline --decorateувидеть компактное дерево.
  3. Скопируйте хеш коммита или его тег, или имя его ветви, если это подсказка.
  4. Запустите команду как:

    git push --force <remote> <commit-ish>:<the remote branch>
    

    например

    git push --force origin 606fdfaa33af1844c86f4267a136d4666e576cdc:master
    

    или

    git push --force staging v2.4.0b2:releases
    

Я использую удобный псевдоним ( git go) для просмотра истории, как на шаге 2, который можно добавить следующим образом:

    git config --global alias.go 'log --graph --all --decorate --oneline'`
WALF
источник
3
График был очень хорошим советом, я просто добавил -5, чтобы получить только последние n коммитов, это было огромное дерево. Также избегать сброса это то, что я искал. Отлично
AlexanderD
@AlexanderD Вы также можете добавить псевдоним в Git, а не в свою оболочку, чтобы он работал везде. Git понимает эти псевдонимы и завершает табуляцию из полной команды, поэтому вы можете добавлять аргументы. git config --global alias.graph 'log --graph --all --decorate --oneline'менее запутанна , и вы все еще можете ограничить его, например:git graph -5
WALF
Это потрясающе. Я всегда испортил мои местные. Это было именно то, что мне было нужно после того, как я случайно запустил свою постановку :( Спасибо!
Джейк,
1
В Windows введите qдля выхода из журнала git. 2 минуты я никогда не вернусь.
dst3p
1
@ dst3p Это на каждой платформе, приятель. Программа пейджера обычно lessи qявляется нормальным способом выхода из нее. Git Bash похож на * nix терминал.
Уолф
63

Я решил проблему, подобную вашей, с помощью следующих команд:

git reset --hard <commit-hash> 
git push -f <remote> <local branch>:<remote branch> 
Иброхим Ерматов
источник
13

На GitLab вам, возможно, придется установить незащищенную ветку перед тем, как сделать это. Вы можете сделать это в [repo]> Настройки> Репозиторий> Защищенные ветви. Тогда метод из ответа Марка работает.

git reset --hard <commit-hash>
git push -f origin master
dudasaus
источник
10

Если вам нужна предыдущая версия файла, я бы порекомендовал использовать git checkout.

git checkout <commit-hash>

Это вернет вас в прошлое, это не повлияет на текущее состояние вашего проекта, вы можете перейти на mainline git checkout mainline

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

git checkout <commit-hash> -- file_name
git add .
git commit -m 'file brought from previous time'
git push

Преимущество этого в том, что он не удаляет историю и не отменяет определенные изменения кода (git revert)

Проверьте больше здесь https://www.atlassian.com/git/tutorials/undoing-changes#git-checkout

Прия Хохер
источник
Это отличный ответ: это работает, период и очень безопасно; если ты испортишь это, легко вернуться.
Боб
8

Мои два цента на предыдущие ответы: если

git push --force <remote> <the-hash>:<the remote branch>

все еще не работает, вы можете отредактировать <your-remote-repo>.git/configсекцию приема файла:

[receive]
  #denyNonFastforwards = true
  denyNonFastforwards = false
badbishop
источник
Полезно знать, как настроить удаленный сервер, чтобы разрешить отправку без ускоренной пересылки, поскольку большинство ответов, по-видимому, предполагают наличие удаленного сервиса, такого как github или bitbucket.
strongbutgood
2

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

git checkout 000000

(где 000000 - это идентификатор коммита, куда вы хотите перейти) в вашей проблемной ветке, а затем просто создайте новую ветку:

git remote add [name_of_your_remote]

Тогда вы можете создать новый пиар, и все будет работать нормально!

Херардо Суарес
источник
1

Сделай одну вещь, получи SHA комита нет. такие как 87c9808, а затем,

  1. переместите себя, это ваша голова к указанному коммиту (выполнив git reset --hard 89cef43 // укажите здесь свой номер)
  2. Затем внесите некоторые изменения в случайный файл, чтобы git попросил вас зафиксировать это локально, а затем удаленно. Итак, что вам нужно сделать сейчас. после применения изменения git commit -a -m "trial commit"
  3. Теперь нажмите следующую фиксацию (если она была зафиксирована локально) мастером git push origin
  4. Теперь то, что мерзость спросит у вас, это

ошибка: не удалось отправить некоторые ссылки на подсказку « https://github.com/YOURREPOSITORY/AndroidExperiment.git »: обновления были отклонены, поскольку подсказка вашей текущей ветви находится за подсказкой: ее удаленным аналогом. Интегрируйте удаленные изменения (например, подсказка: «git pull ...») перед повторным нажатием. **

  1. Таким образом, теперь то, что вы можете сделать, это

git push --force origin master

  1. И, таким образом, я надеюсь, что это работает :)
Сиддхарт Чоудхари
источник
1

Sourcetree: сброс пульта до определенного коммита

  1. Если вы отправили неверный коммит на ваш пульт (origin / feature / 1337_MyAwesomeFeature), как показано ниже

Перейти к Remotes

  1. Перейдите в Remotes> происхождение> функция> 1337_MyAwesomeFeature
  2. Щелкните правой кнопкой мыши и выберите «Удалить источник / элемент / 1337_MyAwesomeFeature» (или измените его имя, если вы хотите создать резервную копию, и пропустите шаг 4).
  3. Нажмите «Принудительно удалить» и «ОК».

введите описание изображения здесь введите описание изображения здесь

  1. Выберите ваш старый коммит и выберите «Сбросить текущую ветку до этого коммита»
  2. Выберите, какой режим вы хотите иметь (жесткий, если вы не хотите, чтобы ваши последние изменения) и "ОК".

введите описание изображения здесь введите описание изображения здесь

  1. Нажмите эту фиксацию для нового источника / feature / 1337_MyAwesomeFeature введите описание изображения здесь

  2. Ваша локальная ветвь функций и ваша удаленная ветвь функций теперь находятся на предыдущем (на ваш выбор) коммите введите описание изображения здесь

Джоэл Виклунд
источник