Как отменить локальные коммиты в Git?

264

Я работал над чем-то, и решил, что это было полностью испорчено ... после совершения некоторых из них. Поэтому я попробовал следующую последовательность:

git reset --hard
git rebase origin
git fetch
git pull
git checkout

В какой момент я получил сообщение

Your branch is ahead of 'origin/master' by 2 commits.

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

Даниэль С. Собрал
источник
6
Нет необходимости делать оба, git fetchи git pull- pull - это комбинация выборки и слияния.
эфир
12
Примечание для пользователей: основная проблема этого вопроса не имеет ничего общего с сообщением «Ваша ветвь опережает« origin / master »на N коммитов». , Пожалуйста, прекратите закрывать другие вопросы как дубликаты этого вопроса из-за этого сообщения.

Ответы:

582
git reset --hard origin/master

удалит все коммиты не origin/masterтам, где originнаходится имя репо и masterимя ветки.

mipadi
источник
1
Я думал, что синтаксис «происхождение / мастер», с косой чертой, относится к локальному репо?
Даниэль С. Собрал
9
mipadi: более правильно, это сбросит текущую ветку, чтобы указать на тот же коммит, что и origin / master.
Кристоффер Хаммарстрем
Это относится к ветке. origin/masterэто ветка, которая отслеживает masterветку originудаленного репо.
Мипади
@ DanielC.Sobral Нет, origin/masterэто ссылка на masterветку удаленного вызова origin.
Мэтью
1
@littletiger git не отслеживает папки, только файлы и их пути. Поэтому он будет полностью игнорировать пустые папки (папки без файлов или только игнорируемые файлы). Они нигде не появляются, потому что им нечего идти.
Mumbleskates
33

Кроме того, помимо ответа от mipadi (который, кстати, должен работать), вы должны знать, что делаете:

git branch -D master
git checkout master

также делает именно то, что вы хотите без having to redownload everything(ваша цитата перефразирована). Это потому, что ваше локальное хранилище содержит копию удаленного хранилища (и эта копия не совпадает с вашей локальной папкой, она даже не совпадает с вашей извлеченной веткой).

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

Если у вас нет других веток, кроме master, вам следует:

git checkout -b 'temp'
git branch -D master
git checkout master
git branch -D temp
slebetman
источник
4
Но как это отличает коммиты, сделанные локально от коммитов, сделанных в источнике? На самом деле, это говорит мне, чтоCannot delete the branch 'master' which you are currently on.
Даниэль С. Собрал
1. В основном все коммиты одинаковы, независимо от того, были ли они сделаны локально или в источнике. Важно то, что истории синхронизированы правильно. Ваша локальная фиксация будет существовать в источнике только после того, как вы их отправили, и по умолчанию git откажется от отправки, если история в источнике может оказаться в состоянии, которое не имеет смысла.
Slebetman
2
2. Конечно, вы не можете удалить ветку, которая в данный момент извлечена. Чтобы удалить мастер, сначала проверьте другую ветку. Если нет другой ветки, просто создайте временную:git checkout -b temp;git branch -D master;git checkout master;git branch -D temp
slebetman 7.10.10
Также обратите внимание на то, что я сказал о том, что ваша локальная копия удаленного репо отличается: git не позволит вам редактировать или даже просматривать файлы в вашей копии удаленной ветки. Это только позволит вам создать другую ветку из удаленной ветки, которую вы затем сможете просматривать и редактировать. По соглашению эта локальная ветвь имеет то же имя, что и удаленная ветвь. Вы частично правы в том, что находитесь origin/masterна своей локальной машине. Это ваша локальная (полная) копия удаленной ветки. Настоящая удаленная ветка есть origin master.
Slebetman
Это сработало для меня. Возможно, в git branch -D masterэтом нет необходимости, поскольку, как указывалось выше, это приводит к ошибке.
Алексис Уилке
15

Что я делаю, так это стараюсь сбросить в HEAD. Это уничтожит все локальные коммиты:

git reset --hard HEAD^
Джан Нгуен
источник
Это лучший ответ, который действительно сработал. Отбрасывает все локальные коммиты и сбрасывает в HEAD. Какая польза от ^ char?
Karim
@karim '^' - это, вероятно, материал для регулярных выражений, который, вероятно, является чем-то довольно глубоким, что я не знаю или не читал давно в файле руководства .. извините, чувак :)
giang nguyen
1
Позднее, но ^представляет родительский коммит, поэтому восстановление HEAD^сбрасывает непринятые изменения и перемещает ветвь к предыдущему коммиту, фактически «удаляя» самый последний коммит (хотя коммит все еще существует, ветвь просто не указывает на него). В ответе будет только один локальный коммит, а остальные - незафиксированные изменения. @karim @giang
QuantumQuaver
3

Вам нужно бежать

git fetch

Чтобы получить все изменения, а затем вы не получите сообщение с «ваша ветка впереди».

Володимир Пасіка
источник
5
Выборка не имеет ничего общего с главной проблемой аскера, которая заключается в избавлении от локальных коммитов.
1
Что делать, если я уже зафиксировал файлы в локальной и затем пытается запустить упомянутую команду. Появится то же сообщение об ошибке. Я попробовал git fetch и git fetch -p тоже. но показывает ту же ошибку
Морез
1

Я видел случаи, когда пульт был не синхронизирован и нуждался в обновлении. Если reset --hardили branch -Dне работает, попробуйте

git pull origin
git reset --hard 
Джим Клаус
источник
это не отвечает на вопрос, reset --hardработает в этой ситуации
CharlesB
1
Привет, Чарльз, ты прав, что reset --hardдолжно сработать здесь. Тем не менее, я просто указываю на то, что иногда не удается правильно сбросить ветку, и a git pull originбудет синхронизироваться с пультом дистанционного управления и позволит reset --hardфункционировать должным образом.
Джим Клаус
0

Я должен был сделать:

git checkout -b master

как мерзавец сказал, что его не существует, потому что он был стер с

git -D master
скат
источник