Различные способы удаления локальных изменений в Git


625

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

Короче говоря, мне пришлось выполнить следующие две команды, чтобы удалить мои локальные изменения

git checkout .

git clean -f

Мой вопрос

(1) Это правильный подход к избавлению от локальных изменений, или, пожалуйста, дайте мне знать правильный подход.

(2) когда мы используем, git reset --hardкак я могу сбросить даже без этой команды

Спасибо

* Решение: Major Edit (s): 26/26: * Заменены многие расплывчатые термины на специфическую для git терминологию [отслежены / не отслежены / поставлены / не установлены)

При локальных изменениях может быть только три категории файлов:

Тип 1. Staged Tracked файлы

Тип 2. Unstaged Отслеживаемые файлы

Тип 3. Unstaged UnTracked файлы или UnTracked файлы

  • Staged - те, которые перемещены в область подготовки / добавлены в указатель
  • Отслеженные - измененные файлы
  • UnTracked - новые файлы. Всегда неподготовленный Если постановка, это означает, что они отслеживаются.

Что делают каждая команда:

  1. git checkout . - УДАЛЯЕТ ТОЛЬКО НЕСТАГИРОВАННЫЕ СЛЕДУЮЩИЕ файлы [Тип 2]

  2. git clean -f - УДАЛЯЕТ НЕУСТАНОВЛЕННЫЕ НЕПРАВИЛЬНЫЕ файлы ТОЛЬКО [Тип 3]

  3. git reset --hard - Удаляет ТОЛЬКО Staged Tracked и UnStaged Tracked файлы [Тип 1, Тип 2]

  4. git stash -u - Удаляет все изменения [Тип 1, Тип 2, Тип 3]

Вывод:

Понятно, что мы можем использовать либо

(1) combination of `git clean -f` and `git reset --hard` 

ИЛИ

(2) `git stash -u`

достичь желаемого результата.

Примечание: копить, так как слово означает «Хранить (что-то) безопасно и тайно в указанном месте». Это всегда можно получить с помощью git stash pop. Поэтому выбор между двумя вышеупомянутыми вариантами - это вызов разработчика.

Спасибо Кристоф и Фредерик Шёнинг.

Изменить: 03/27

Я думал, что стоит поставить « остерегаться » запискуgit clean -f

git clean -f

Там нет пути назад. Используйте -nили --dry-runдля предварительного просмотра ущерба, который вы нанесете.

Если вы хотите также удалить каталоги, запустите git clean -f -d

Если вы просто хотите удалить игнорируемые файлы, запустите git clean -f -X

Если вы хотите удалить как игнорируемые, так и не проигнорированные файлы, запустите git clean -f -x

ссылка: подробнее git clean: Как удалить локальные (неотслеживаемые) файлы из текущего рабочего дерева Git?

Редактировать: 20.05.15

Отмена всех локальных коммитов в этой ветке [Удаление локальных коммитов]

Чтобы отменить все локальные коммиты в этой ветке, чтобы сделать локальную ветвь идентичной "восходящему" из этой ветки, просто запустите git reset --hard @{u}

Ссылка: http://sethrobertson.github.io/GitFixUm/fixup.html

или сделайте git reset --hard origin/master[если местный филиал master]

Примечание: 12.06.2015 Это не дубликат другого SO вопроса, который помечен как дубликат. Этот вопрос посвящен тому, как удалить локальные изменения GIT [удалить добавленный файл, удалить изменения, добавленные в существующий файл и т. Д., А также различные подходы; Где в другом потоке SO только адрес, как удалить локальный коммит. Если вы добавили файл и хотите удалить его в одиночку, то другой поток SO не обсуждает его. Следовательно, это не дубликат другого]

Изменить: 23.06.15

Как восстановить коммит, уже переданный в удаленный репозиторий?

$ git revert ab12cd15

Изменить: 01.09.2015

Удалить предыдущий коммит из локальной ветки и удаленной ветки

Случай: Вы только что внесли изменения в свой локальный филиал и сразу же отправили в удаленный филиал, внезапно осознав: о, нет! Мне не нужно это изменение. Теперь что делать?

git reset --hard HEAD~1 [для удаления этого коммита из локальной ветки]

git push origin HEAD --force[обе команды должны быть выполнены. Для удаления из удаленной ветки]

Что за ветка? Это проверенная ветка.

Редактировать 09/08/2015 - Удалить локальное слияние мерзавцев :

Я нахожусь на masterветке и слил masterветку с вновь работающей веткойphase2

$ git status
# On branch master

$ git merge phase2

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 8 commits.

Q: Как избавиться от этого слияния? Пробовал git reset --hard и git clean -d -f оба не работали.

Единственное, что сработало, это одно из следующих:

$ git reset --hard origin/master

или

$ git reset --hard HEAD~8

или

$ git reset --hard 9a88396f51e2a068bb7 [sha commit code - это тот, который присутствовал до того, как произошли все ваши коммиты]


1
Я думаю, эта ветка может ответить на ваши вопросы: stackoverflow.com/questions/1146973/…
Saucier

1
«git stash» удалит все сделанные вами изменения.
Джон Баллинджер

1
Хорошее резюме! Я бы добавил еще одну категорию файлов: «Тип 4. Игнорируемые файлы». git stash -a[или --all] также хранит игнорируемые и неотслеживаемые файлы. git clean -xтакже будет очищать игнорируемые файлы. git clean -Xбудет чистить только проигнорированные файлы.
Jerry101

2
@JavaDev Ваш вопрос был больше похож на ответ ... спасибо, что вы продолжали редактировать и собирали все ответы.
Бхавук Матур

1
спасибо, я выполнил все 4 твои команды, чтобы отменить локальные изменения
Vincent Tang

Ответы:


505

Все зависит от того, что именно вы пытаетесь отменить / отменить. Начните с чтения поста в ссылке Убе . Но чтобы попытаться ответить:

Аппаратный сброс

git reset --hard [HEAD]

полностью удалить все поэтапные и неустановленные изменения в отслеживаемых файлах.

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

чистый

git clean [-f]

Удалить файлы, которые не отслеживаются.

Для удаления временных файлов, но сохраняйте поэтапные и немаркированные изменения уже отслеженных файлов. В большинстве случаев я бы, вероятно, закончил бы созданием правила игнорирования вместо неоднократной очистки - например, для папок bin / obj в проекте C #, которые вы обычно хотели бы исключить из своего репозитория для экономии места, или что-то в этом роде.

Опция -f (force) также удаляет файлы, которые не отслеживаются и также игнорируются git, хотя ignore-rule. В приведенном выше случае с правилом игнорирования никогда не отслеживать папки bin / obj, даже если git игнорирует эти папки, использование опции force удалит их из вашей файловой системы. Я время от времени видел использование этого, например, при развертывании сценариев, и вы хотите очистить свой код перед его развертыванием, архивированием или чем-то еще.

Git clean не будет трогать файлы, которые уже отслеживаются.

Оформить заказ "точка"

git checkout .

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

msgstr "отменить все изменения в моем рабочем дереве".

Т.е. отменить неустановленные изменения в отслеживаемых файлах. По-видимому, он не затрагивает поэтапные изменения и оставляет неотслеживаемыми файлы в покое.

припрятать

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

Подводить итоги

Как правило, если вы уверены, что вы совершили и, возможно, подтолкнули к удаленным важным изменениям, если вы просто играете или что-то подобное, использование с git reset --hard HEADпоследующим git clean -fбудет окончательно очистит ваш код до состояния, в котором он был бы, если бы он был клонирован и проверил из ветки. Очень важно подчеркнуть, что сброс также удалит поэтапные, но незафиксированные изменения. Это сотрет все, что не было зафиксировано (кроме неотслеживаемых файлов, в этом случае используйте clean ).

Все остальные команды существуют для облегчения более сложных сценариев, где требуется гранулярность «отмены» :)

Я чувствую, ваш вопрос № 1 покрыт, но, наконец, заключаю № 2: причина, по которой вы никогда не находили необходимость использовать, git reset --hardзаключалась в том, что вы никогда ничего не ставили. Если бы вы устроили изменение, ни git checkout .отменили git clean -fбы это.

Надеюсь, что это охватывает.


Спасибо за причину использования git reset --hard. Я попробовал это, и да .. те файлы , добавленные в индекс (постановки) были удалены только после того, как git reset --hard, и я предполагаю , что по умолчанию git reset --hardявляется git reset --hard head. Эта ссылка также была полезна gitready.com/beginner/2009/01/18/the-staging-area.html
spiderman

Я улучшил свой ответ, почему я думаю, git stash -uчто здесь больше всего смысла.
Кристоф

2
Спасибо вам обоим. Я суммировал ответ и включил в свой вопрос. Кристоф дал мне знать, что git stash -uделает и как это сделать, но Фредерик дал мне знать, что перезагрузить сложно, используя комбинацию git reset --hardи git clean -f, и почему нет stash, предпочтительнее в некоторых сценариях. Теперь, пожалуйста, помогите мне выбрать, какой из них я должен пометить как ответ :), оба мои ответы.
паук

3
.является путевой спецификацией, ссылающейся на текущий рабочий каталог, который может быть корнем хранилища. С git-scm.com: git checkout [<tree-ish>] [--] <pathspec>…обновляет именованные пути в рабочем дереве из индексного файла или из <tree-ish>.
Jerry101

3
Никогда не подчеркивалось, что и то, git reset --hardи другое, git clean -dfxявляются разрушительными . В любом случае, пожалуйста, исправьте строчную букву headв ответе, она должна быть либо заглавной, HEADлибо вообще отсутствовать.
Павел Шимерда

25

Причина добавления ответа на данный момент:

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

Я также добавил более часто используемые команды git, которые помогают мне в git, чтобы помочь кому-то еще.

В основном, чтобы очистить все местные коммиты $ git reset --hardи $ git clean -d -f


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

# Устанавливает имя, которое вы хотите прикрепить к вашим транзакциям фиксации

$ git config --global user.name "[name]"

# Устанавливает электронное письмо, которое вы хотите прикрепить к вашим транзакциям фиксации

$ git config --global user.email "[email address]"

# Перечислите глобальный конфиг

$ git config --list

# Перечислите удаленный URL

$ git remote show origin

#Проверь состояние

git status

# Перечислите все локальные и удаленные филиалы

git branch -a

# создайте новую локальную ветку и начните работать над этой веткой

git checkout -b "branchname" 

или, это может быть сделано в два этапа

создать ветку: git branch branchname работать в этой ветке:git checkout branchname

#commit local changes [двухэтапный процесс: - Добавить файл в индекс, что означает добавление в промежуточную область. Затем зафиксируйте файлы, которые присутствуют в этой промежуточной области.]

git add <path to file>

git commit -m "commit message"

# проверить другой местный филиал

git checkout "local branch name"

# удалить все изменения в локальной ветке [Предположим, вы внесли некоторые изменения в локальную ветку, например добавили новый файл или изменили существующий файл, или сделали локальный коммит, но больше не нуждались в этом] git clean -d -fи git reset --hard [удалите все локальные изменения, сделанные в локальной ветке, кроме случаев, когда местный коммит]

git stash -u также удаляет все изменения

Примечание: Это ясно , что мы можем использовать либо (1) комбинацию git clean –d –fи git reset --hard OR (2) git stash -u для достижения желаемого результата.

Примечание 1: Скрытие, поскольку слово означает «Хранить (что-то) безопасно и тайно в указанном месте». Это всегда можно получить с помощью git stash pop. Поэтому выбор между двумя вышеупомянутыми вариантами - это вызов разработчика.

Примечание 2: git reset --hardудалит изменения рабочего каталога. Обязательно сохраните все локальные изменения, которые вы хотите сохранить, перед запуском этой команды.

# Переключитесь на главную ветку и убедитесь, что вы в курсе.

git checkout master

git fetch [это может быть необходимо (в зависимости от вашего git config), чтобы получать обновления на origin / master]

git pull

# Объединить ветку объектов в главную ветку.

git merge feature_branch

# Сбросьте основную ветвь в исходное состояние.

git reset origin/master

# Случайно удалил файл из локального, как вернуть его обратно? Сделайте, git statusчтобы получить полный путь к файлу удаленного ресурса

git checkout branchname <file path name>

это оно!

#Merge мастер ветка с someotherbranch

git checkout master
git merge someotherbranchname

# переименовать местное отделение

git branch -m old-branch-name new-branch-name

# удалить местное отделение

git branch -D branch-name

# удалить удаленную ветку

git push origin --delete branchname

или

git push origin :branch-name

# вернуть коммит, уже переданный в удаленный репозиторий

git revert hgytyz4567

# ответвление от предыдущего коммита с использованием GIT

git branch branchname <sha1-of-commit>

# Изменить сообщение о коммите самого последнего коммита, который уже был передан на удаленный

git commit --amend -m "new commit message"
git push --force origin <branch-name>

# Отмена всех локальных коммитов в этой ветке [Удаление локальных коммитов]

Чтобы отменить все локальные коммиты в этой ветке, чтобы сделать локальную ветвь идентичной "восходящему" из этой ветки, просто запустите

git reset --hard @{u}

Ссылка: http://sethrobertson.github.io/GitFixUm/fixup.html или сделайте git reset --hard origin/master[если локальная ветвь является главной]

# Вернуть коммит, уже переданный в удаленный репозиторий?

$ git revert ab12cd15

# Удалить предыдущий коммит из локальной ветки и удаленной ветки

Сценарий использования: вы просто передали изменения в свой локальный филиал и сразу же отправили в удаленный филиал, внезапно осознав: о нет! Мне не нужно это изменение. Теперь что делать?

git reset --hard HEAD~1[для удаления этого коммита из локальной ветки. 1 обозначает ОДИН коммит, который вы сделали]

git push origin HEAD --force[обе команды должны быть выполнены. Для удаления из удаленной ветки. В настоящее время извлеченная ветвь будет называться веткой, в которой вы выполняете эту операцию.

# Удалите некоторые недавние коммиты из локального и удаленного репо и сохраните коммит, который вы хотите. (своего рода возврат коммитов с локального и удаленного)

Предположим, у вас есть 3 коммита, которые вы отправили в удаленную ветку с именем ' develop'

commitid-1 done at 9am
commitid-2 done at 10am
commitid-3 done at 11am. // latest commit. HEAD is current here.

Вернуться к старому коммиту (изменить состояние ветки)

git log --oneline --decorate --graph // чтобы увидеть все ваши комидиды

git clean -d -f // убираем любые локальные изменения

git reset --hard commitid-1 // локально возвращаемся к этому коммиту

git push -u origin +develop// перевести это состояние в удаленное состояние. + сделать принудительный толчок

# Удалить локальное git merge: Case: Я нахожусь в главной ветке и слил главную ветку с недавно работающей ветвью phase2

$ git status

На ветке мастер

$ git merge phase2 $ git status

На ветке мастер

Ваша ветка опережает 'origin / master' на 8 коммитов.

Q: Как избавиться от этого локального git merge? Пробовал git reset --hardи git clean -d -fоба не работали. Единственное, что сработало, это одно из следующих:

$ git reset --hard origin / master

или

$ git reset --hard HEAD ~ 8

или

$ git reset --hard 9a88396f51e2a068bb7 [sha commit code - это тот, который присутствовал до того, как произошли все ваши коммиты]

#create gitignore file

touch .gitignore // создаем файл в mac или unix пользователях

Пример содержимого .gitignore:

.project
*.py
.settings

Ссылка на шпаргалку GIT: https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf


1
Ваша команда для удаления удаленной ветви может быть не самой лучшей . Вы используете, git push origin :branch-nameоднако я рекомендую использоватьgit push origin --delete branchname
Vibs2006

Согласитесь, я обновил ваше предложение, спасибо @ vibs2006
паук

21

Как и все в git, есть несколько способов сделать это. Две команды, которые вы использовали, являются одним из способов сделать это. Еще одна вещь, которую вы могли бы сделать - просто спрятать их git stash -u. Он -uгарантирует, что вновь добавленные файлы (без отслеживания) также включены.

Удобная вещь о git stash -uтом, что

  1. это, вероятно, самая простая (только?) единственная команда для достижения вашей цели
  2. если после этого вы передумаете, вы вернете всю свою работу git stash pop(это похоже на удаление электронного письма в gmail, где вы можете просто отменить, если потом передумаете)

На ваш другой вопрос git reset --hardне будут удалены неотслеживаемые файлы, так что вам все равно понадобится git clean -f. Но git stash -uможет быть самым удобным.


git reset --hardне будет удалять неотслеживаемые файлы на самом деле, но это будет удалить неотслеживаемые изменения, то есть изменения в файлы, которые уже находятся в индексе. Я уверен, что это то, что вы имели в виду :)
Фредерик Штрук-Шенинг,

Когда я использовал git stash -u, я увидел этот ответ от git bash. «Сохраненный рабочий каталог и состояние индекса WIP на {branchname}. Может быть, этот сохраненный файл - то, что мы могли бы извлечь с помощью git stash pop.
spiderman

Спасибо вам обоим. Я суммировал ответ и включил в свой вопрос. Кристоф дал мне знать, что git stash -uделает и как это сделать, но Фредерик дал мне знать, что перезагрузить сложно, используя комбинацию git reset --hardи git clean -f, и почему нет stash, предпочтительнее в некоторых сценариях. Теперь, пожалуйста, помогите мне выбрать, какой из них я должен пометить как ответ :), оба мои ответы.
паук

но что если в моем репозитории есть файл, который я не хочу отслеживать? только в моем репо. Если я добавлю его в список игнорирования, то у меня будет файл .ignore для фиксации, который также повлияет на всех остальных.
user20358

7

1. Когда вы вообще не хотите сохранять свои локальные изменения.

git reset --hard

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

2. Когда вы хотите сохранить свои локальные изменения

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

git stash

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

git pull

Теперь вы можете вернуть свои локальные изменения,

git stash pop

1
git reset --hardне удаляет все локальные изменения. Это только удаляет модификации. Если вы хотите удалить добавления, то вы также должныgit clean -fd
Джон Хенкель


4

Я думаю, что у git есть одна вещь, которая не совсем задокументирована. Я думаю, что это на самом деле пренебрегли.

git checkout .

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

Там в git clean -fd хорошо работает для неотслеживаемых файлов.

Затем git resetпросто удаляет постановку, но git checkoutэто слишком громоздко. Указывать файл по одному или использовать каталоги не всегда идеально. Иногда измененные файлы, от которых я хочу избавиться, находятся в каталогах, которые я хочу сохранить. Я пожелал этой единственной команды, которая просто удаляет необработанные изменения, и вот вы здесь. Спасибо.

Но я думаю, что они должны просто иметь git checkoutбез каких-либо опций, удалить все неустановленные изменения и не трогать поставленные. Это своего рода модульный и интуитивно понятный. Больше похоже на то, что git resetделает. git cleanТакже следует сделать то же самое.


2

Лучший способ проверить изменения.

Изменяя файл pom.xml в проекте с именем project-name, вы можете сделать это:

git status

# modified:   project-name/pom.xml

git checkout project-name/pom.xml
git checkout master

# Checking out files: 100% (491/491), done.
# Branch master set up to track remote branch master from origin.
# Switched to a new branch 'master'

2

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

Это сохранит все изменения в {0}ключе и мгновенно отбросит его из{0}

git stash && git stash drop


1

Прежде всего, проверьте, сохранены или нет важные изменения:

$ git status

чем попробовать

$ git reset --hard

это сбросит вашу ветку по умолчанию

но если вам нужно просто отменить:

$ edit (1) $ git add frotz.c filfre.c $ mailx (2) $ git reset
(3) $ git pull git: //info.example.com/ nitfol


Читать дальше >> https://git-scm.com/docs/git-reset


Примечание: команда reset --hard является опасной, она удалит все изменения и не может быть отменена. Пользователь должен знать, при использовании сброса трудно.
danglingpointer
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.