Откат локального и удаленного репозитория git на 1 коммит

188

Я читал похожие посты на эту тему и не могу понять, как это сделать правильно.

Я зарегистрировал около 1000 файлов, которые мне не нужны, и я бы предпочел не проходить 1by1 и удалить их все из репо.

  • У меня есть удаленный masterфилиал.
  • У меня есть местное masterотделение.

Они оба в одной ревизии.

Я хочу откатить свой пульт на 1 коммит.

Скажи мою историю на masterтом A--B--C--D--E.
Я хочу откатить свой локальный до D.
Затем отправьте его на удаленный компьютер, чтобы мой текущий хеш был D удаленным и локальным.

У меня проблемы с этим.
Я использую Git Tower, но мне удобно работать с командной строкой. Любая помощь?

ОБНОВЛЕНИЕ: большие комментарии ниже. Использование сброса не рекомендуется, особенно если хранилище используется совместно с другими пользователями. Каков наилучший способ отменить изменения предыдущего коммита без использования аппаратного сброса ? Есть ли способ?

Джемис чарльз
источник
Я обновил свой ответ, чтобы «отменить изменения предыдущего коммита без использования аппаратного сброса».
VonC
3
Используйте git revertдля выполнения без полной перезагрузки и не мешая пользователям.
user562374
2
Возможный дубликат
коммитов
Отказ от дистанционного управления - это то, что не рекомендуется, но если это то, что вы хотите сделать, сделайте это. Есть сотни способов сделать это, но результат будет таким же на стороне сервера.
FelipeC

Ответы:

307

Если никто еще не вытащил ваше удаленное репо, вы можете изменить заголовок ветки и принудительно перенести его в указанное удаленное репо:

git reset --hard HEAD^ 
git push -f 

(или, если у вас есть прямой доступ к удаленному репо, вы можете изменить его ссылку на HEAD, даже если это пустое репо )

Обратите внимание, что, как прокомментировал Alien-Technology в комментариях ниже , для Windows (сеанс CMD), вам потребуется ^^:

git reset --hard HEAD^^
git push -f 

Обновление с 2011 года:
использование git push --force-with-lease( которое я представляю здесь , представленное в 2013 году с Git 1.8.5) более безопасно.

См Schwern «s ответ на иллюстрации.


Что делать, если кто-то уже вытащил репо? Что бы я тогда делал?

Тогда я бы предложил что-то, что не переписывает историю:

  • git revert локально ваш последний коммит (создание нового коммита, который полностью изменяет то, что делал предыдущий коммит)
  • нажмите 'вернуть' сгенерированный git revert.
VonC
источник
1
Что делать, если кто-то уже вытащил репо? Что бы я тогда делал?
Джемис Чарльз
1
@gwho создает ветку? Нет, он перемещает ГОЛОВУ ветви, но вы все еще находитесь в той же ветви. Тем не менее, так как толчок больше не ускоренный, да, вам нужно форсировать этот толчок.
VonC
1
Есть ли способ узнать, если кто-то вытащил репо?
Пинкертон
4
В Windows символ ^ используется для продолжения строки и для экранирования символа, выполнив команду: git reset --hard HEAD ^^
Alien Technology
1
@AlienTechnology Используя Powershell, в Windows 10 мне нужно было только набрать, reset --hard HEAD^а не reset --hard HEAD^^сбрасывать последний коммит.
Гаспаччо
58

Установить локальную ветвь на одну ревизию назад ( HEAD^значит, на одну ревизию назад):

git reset --hard HEAD^

Нажмите изменения к источнику:

git push --force

Вам придется принудительно нажимать, потому что в противном случае git признает, что вы отстали originна один коммит, и ничего не изменится.

Выполнение этого --forceзаставляет git перезаписывать HEADв удаленном репо без учета каких-либо достижений.

Экес
источник
1
Я бы посоветовал не называть это возвратом, поскольку это специфический термин с совершенно другим значением в git.
Каскабель
@Jefromi: Спасибо за подсказку. Ред.
Eckes
Отличный ответ. Я читал, что использование сброса, похоже, частично не рекомендуется, особенно если хранилище используется совместно с другими пользователями. Есть ли более чистый способ сделать это, который отменяет все изменения вашего предыдущего коммита?
Джеймис Чарльз
Быть осторожен! Спрятать свои незафиксированные изменения или потерянные ими
Носов Павел
Это классно. Итак, означает ли это, что когда мы это сделаем git push origin master, Git сможет создать новый коммит на удаленном компьютере, потому что локальная ветвь впереди хотя бы один раз? Кроме того, последнее должно существенно отличаться от того, на что указывает руководитель удаленного репо?
MadPhysicist
18

Если вы хотите отменить последний коммит, прослушайте:

Шаг 1:

Проверьте ваши локальные коммиты с сообщениями

$ git log

Шаг 2:

Удалить последний коммит без сброса изменений из локальной ветки (или мастера)

$ git reset HEAD^

ИЛИ, если вы не хотите, чтобы последние файлы коммитов и обновления слушали

$ git reset HEAD^ --hard

Шаг 3:

Мы можем обновить файлы и коды и снова нажать с силой, чтобы удалить предыдущий коммит. Это сохранит новый коммит.

$ git push origin branch -f

Это оно!

Каннан С
источник
Это не возврат коммита, это замена одного. Пожалуйста, не вводите нас в заблуждение новичками, злоупотребляя обычными условиями.
Suncat2000
7

Введя ниже команду, вы можете увидеть историю ваших изменений в git -

$ git log

Допустим, ваша история в этой конкретной ветке похожа на - commit_A, commit_B, commit_C, commit_D. Где commit_D - последний коммит, и именно здесь HEAD остается. Теперь, чтобы удалить ваш последний коммит из локального и удаленного, вам нужно сделать следующее:

Шаг 1: Удалить последний коммит локально с помощью -

$ git reset --hard HEAD ~

Это изменит ваш коммит HEAD на commit_C

Шаг 2. Переместите изменения для новой фиксации HEAD на удаленный

$ git push origin + HEAD

Эта команда удалит последний коммит из удаленного.

PS Эта команда протестирована на Mac OSX и должна работать и на других операционных системах (хотя и не на других ОС)

sahilabrar
источник
3

Для Windows машин используйте:

git reset HEAD~1  #Remove Commit Locally
Анвеш Яламарти
источник
3

Вот обновленная версия процедуры, которая безопаснее.

git reset --hard HEAD^ 
git push --force-with-lease

git push -fбез разбора заменит удаленный репозиторий на ваши собственные изменения. Если кто-то еще внес изменения, они будут потеряны. git push --force-with-leaseтолько подтолкнет ваш ребаз, если репозиторий будет таким, как вы ожидаете. Если кто-то еще нажал, ваш толчок потерпит неудачу.

Видите - сила считается вредной; понимание мерзавца - сила с арендой .

Я рекомендую псевдоним это repush = push --force-with-lease.

Что делать, если кто-то уже вытащил репо? Что бы я тогда делал?

Скажи им git pull --rebase=merges. Вместо а так git fetch originи git merge origin/masterбудет git fetch originи git rebase -r origin/master. Это перезапишет любые их локальные изменения masterповерх новых перебазированных origin/master. -rсохранит любые слияния, которые они могли сделать.

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

[pull]
        rebase = merges
Schwern
источник
1
Согласились и проголосовали. Для моей защиты мой старый ответ 2011 года был написан за два года до введения --force-with-leaseопции.
VonC
Я думал, что уже сделал это (вчера): stackoverflow.com/posts/4647362/revisions
VonC
1

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

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

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

git reset --soft HEAD^

Это работает, поскольку нет попытки изменить несуществующий рабочий каталог. Для более подробной информации, пожалуйста, смотрите оригинальный ответ:

Как я могу отменить последний коммит в репозитории git bare?

Hazok
источник
0

Я просто хотел удалить последний коммит из удаленной и очистить историю коммитов. Следующее работает как шарм

git reset --hard HEAD^ 
git push -f 
minhas23
источник
Но чем «следующее» отличается от моего ответа выше ?
VonC
0

Сбросить голову и вернуться к предыдущему коммиту можно через

$ git reset HEAD^ --hard
$ git push <branchname> -f

Но иногда это может быть не принято в удаленной ветке:

To ssh:<git repo>
 ! [rejected]        develop -> develop (non-fast-forward)
error: failed to push some refs to 'ssh:<git repo>'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

тогда другой способ сделать это

git revert HEAD
git push <remote branch>

Это отлично работает.

ПРИМЕЧАНИЕ: запомните, если произошел git push -f <force>сбой, а затем попытайтесь вернуться. Сделайте это git pullраньше, чтобы удаленный и локальный синхронизировались, а затем попробуйте git revert.
Проверьте, git logчтобы убедиться, что удаленный и локальный находятся в одной точке фиксации с тем же SHA1.

git revert 
A --> B --> C -->D
A--> B --> C --> D --> ^D(taking out the changes and committing reverted diffs)
ravi.zombie
источник
0

на местного мастера

git reflog
-- this will list all last commit
  e.g Head@{0} -- wrong push
      Head@{1} -- correct push  
git checkout Head@{1} .
  -- this will reset your last modified files

git status 
git commit -m "reverted to last best"
git push origin/master

Не нужно беспокоиться, если другие потянули или нет.

Готово!

Бхушан
источник
0

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

git push origin +origin/master~:master

Это использует следующий синтаксис:

git push <remote> <refspec>

Здесь <remote>есть originи <refspec>имеет следующую структуру:

+origin/master~:master

Подробности можно найти в git-push(1). Предыдущее +означает «принудительное нажатие на эту ссылку», а другая часть означает «от origin/master~к master(удаленного origin)». Нетрудно понять, что origin/master~это последний коммит origin/master, верно?

iBug
источник
0

у меня работает эта две команды:

git checkout commit_id
git push origin +name_of_branch
Яхор М
источник
0

Вы также можете сделать это:

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

и сделайте так, чтобы все остальные, кто получил последние сбросы плохих коммитов:

git reset --hard origin/master
A-Sharabiani
источник