git: переключить ветку и игнорировать любые изменения без фиксации


318

Я работал над веткой git и был готов зафиксировать свои изменения, поэтому я сделал коммит с полезным сообщением коммита. Затем я рассеянно внес небольшие изменения в код, которые не стоит хранить. Теперь я хочу сменить ветку, но Git дает мне,

ошибка: у вас есть локальные изменения на «X»; не может переключать ветви.

Могу ли я сменить ветку без коммитов? Если так, как я могу настроить это? Если нет, как мне выйти из этой проблемы? Я хочу игнорировать незначительные изменения без фиксации и просто менять ветки.


1
Я считаю, что это происходит только тогда, когда они внесены изменения для фиксации, но не зафиксированы? git checkout прекрасно работает для смены веток, если вы еще не создали файлы с помощью git add или чего-либо подобного.
Джереми Уолл

1
Привет, Джереми, что ты имеешь в виду под «постановкой»? Принуждение пользователя к фиксации файла перед изменениями не выглядит хорошим рабочим процессом. Например, если я нахожусь в главном репозитории и быстро хочу проверить что-то в ветке. Сначала я должен передать код мастеру, даже если он наполовину написан! Вы говорите, что действительно, в этой ситуации должна быть возможность проверить филиал?
Даниэль Фаррелл

@boyfarrell Вы можете использовать 'Git stash', чтобы временно сохранить изменения без фиксации.
Howiecamp

Перекрестное связывание тесно связанных между собой Как заставить «git pull» перезаписывать локальные файлы?
user56reinstatemonica8

1
когда вы переключаетесь на ветку без фиксации изменений в старой ветке, git пытается объединить изменения с файлами в новой ветке. Если объединение выполняется без каких-либо конфликтов, переходящие ветви будут успешными, и вы сможете увидеть изменения в новой ветви. Но если возникнет конфликт, вы получите error: You have local changes to '<filename>'; cannot switch branches.и ветвь не изменится. Вы можете сделать это, git checkout -m <branch-name>чтобы объединить конфликты и оформить заказ в ветке и разрешить конфликты самостоятельно или git checkout -f <branch-name>игнорировать изменения.
Самад Монтазери

Ответы:


400

Вам нужно чистое состояние, чтобы сменить ветки. Проверка ветки будет разрешена только в том случае, если она не влияет на «грязные файлы» (как замечает Чарльз Бэйли в комментариях).

В противном случае вы должны либо:

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

Или, совсем недавно:

Продолжайте, даже если индекс или рабочее дерево отличается от HEAD.
И индекс, и рабочее дерево восстанавливаются в соответствии с целью переключения.

Это отличается от того git switch -m <branch-name>, что запускает трехстороннее слияние между текущей веткой, содержимым вашего рабочего дерева и новой веткой: готово: таким образом вы не потеряете свою работу в процессе.


34
«Вам нужно чистое состояние, чтобы сменить ветку». Истинно, только если изменение ветки влияет на «грязные файлы».
CB Bailey

10
Для метода stash я набрал «git stash save», «git checkout otherbranch», а затем «git stash pop».
Венкат Д.

1
В настоящее время я не вижу это сообщение об ошибке, и изменения, которые я сделал в одной ветви, отображаются в другой, когда я делаю «git status». что-то изменилось?
Сентил А Кумар

2
Спасибо. проверка -f была то, что мне было нужно. я сделал git reset --hard git clean -f git checkb mybranch -f
nologo

1
Вот одна замечательная вещь, которую Git совершенно ошибся, нарушив базовое определение ветви. В отличие от git ветка означает два совершенно разных рабочих пространства, разветвленных из репозитория.
Нехем,

125

Если вы хотите отменить изменения,

git checkout -- <file>
git checkout branch

Если вы хотите сохранить изменения,

git stash save
git checkout branch
git stash pop

10
Действительно, что говорит Ромерун (чтобы быть полным): git stash save(когда в рабочей ветке Y) затем git checkout branchXчто-то делать git add/commit -mи т. Д. git checkout branchYИ git stash popвернуть тайник
Highmastdon

2
Может быть, так. У меня есть ситуация, когда я хочу сделать то, что говорит ответ, если я правильно понимаю: спрятать изменения, переключиться с Y на X, затем выскочить изменения и зафиксировать их на X.
Бен Кляйн

1
Обратите внимание, что git stash saveтеперь не рекомендуется в пользуgit stash push
Argento

Этот псевдоним упрощает сохранение изменений при смене веток.
Том Хейл,

62

ну, это должно быть

git stash save
git checkout branch
// do something
git checkout oldbranch
git stash pop

5
Да, stash является глобальным, а не специфичным для ветви. Если я переключу pop после переключения ветви, я получу тот же самый stash, что и на другой ветви (-ях)
Aditya Mittal

6
Следует отметить, git stashбудет по умолчаниюgit stash save
Чарли-Гринман

Спасибо, это очень полезно для меня
Говинд Кумар


16

Обратите внимание, что если вы объединили удаленные ветви или имеете локальные коммиты и хотите вернуться к удаленному HEAD, вы должны сделать:

git reset --hard origin/HEAD

HEAD один будет ссылаться только на локальную фиксацию / слияние - несколько раз я забывал, что при сбросе и в конечном итоге "ваш репозиторий - это X коммитов впереди ...", когда я полностью намеревался уничтожить ВСЕ изменения / коммиты и вернуться в удаленную ветку ,


9

Если вы внесли изменения в файлы, которые Git также должен изменить при переключении веток, это не позволит вам. Чтобы отменить рабочие изменения, используйте:

git reset --hard HEAD

Тогда вы сможете переключаться между филиалами.


9

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

git reset --hard HEAD
git clean -d -f

4

переход на новую ветку теряет изменения:

git checkout -b YOUR_NEW_BRANCH_NAME --force

переключение на существующую ветку с потерей изменений:

git checkout YOUR_BRANCH --force

4

Простой ответ:

это заставить оформить ветку

git checkout -f <branch_name>

Принудительное извлечение ветки говорит git отбросить все изменения, которые вы сделали в текущей ветке, и извлеките желаемое.

или в случае, если вы проверяете коммит

git checkout -f <commit-hash>


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

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


Вы решили сохранить изменения?

Затем спрятать их, используя

git stash

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

git stash apply

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

git stash pop

Это эквивалентно, applyа затемdrop


2

Закройте терминал, удалите папку, в которой находится ваш проект, затем снова клонируйте ваш проект и вуаля.


2
git не предназначен для того, чтобы заставить вас удалить проект и снова клонировать! если вы хотите получить последнюю версию из оригинала, вы просто reset --hard!
Ахмед Нур Джамал Эль-Дин

2

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

git stash && git checkout <branch_name> && git stash pop

1

Переместить незафиксированные изменения в новую ветку

Я создал .gitconfigпсевдоним для этого:

[alias]
spcosp = !"git stash push && git checkout \"$@\" && git stash pop --index #"

Чтобы изменить на new-branch-name, используйте:

git spcosp new-branch-name

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


1

git checkout -f your_branch_name

git checkout -f your_branch_name

Если у вас есть проблемы с отменой изменений:

git checkout .

если вы хотите удалить неотслеживаемые каталоги и файлы:

git clean -fd

0

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

git checkout -f имя-филиала

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