Сбросить ветку локального репозитория, чтобы она была похожа на HEAD удаленного репозитория

2702

Как reset моя локальная ветвь будет похожа на ветку в удаленном репозитории?

Я сделал:

git reset --hard HEAD

Но когда я запускаю git status,

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
      modified:   java/com/mycompany/TestContacts.java
      modified:   java/com/mycompany/TestParser.java

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

  • 6
    Согласно выводу состояния git status ваша вторая команда git reset --hard HEAD неудачно. Вы не вставили его вывод, хотя. → Неполный вопрос.
  • 2
    Здесь вы смешиваете две проблемы: 1) как сбросить локальную ветку до точки, где находится удаленный, и 2) как очистить вашу промежуточную область (и, возможно, рабочий каталог), чтобы git status nothing to commit, working directory clean говорил nothing to commit, working directory clean - Пожалуйста уточни!
Теги:
undo

18 ответов

5263
Лучший ответ

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

git fetch origin
git reset --hard origin/master

Если вы хотите сохранить текущее состояние ветвления, прежде чем делать это (на всякий случай), вы можете сделать:

git commit -a -m "Saving my work, just in case"
git branch my-saved-work

Теперь ваша работа сохраняется на ветке "my-saved-work" в случае, если вы решите, что хотите ее вернуть (или хотите посмотреть на нее позже или отнести ее к обновленной ветке).

Обратите внимание, что в первом примере предполагается, что имя удаленного репо является "источником" и что ветвь с именем "master" в удаленном репо совпадает с текущей выпадающей ветвью в вашем локальном репо.

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

  • 3
    Спасибо за ваш ответ. Вы сказали: «Обратите внимание, что в первом примере предполагается, что имя удаленного репо -« origin », и что ветка с именем« master »в удаленном репо совпадает с веткой в вашем локальном репо». Как я могу дважды проверить имя моего удаленного репо и имя моей ветви, чтобы быть уверенным, прежде чем я выполню 'git reset --hard'? Еще раз спасибо.
  • 17
    Если вы не указали имя пульта в явном виде, то его имя, скорее всего, просто «происхождение» (по умолчанию). Вы можете использовать «git remote», чтобы получить список всех удаленных имен. Затем вы можете использовать «git remote <name>», чтобы увидеть, какие ветви push / pull друг с другом (например, если ваша «master» ветка была клонирована из «master» в удаленном устройстве с именем «origin», то вы получите строку что говорит "мастер сливается с удаленным мастером").
Показать ещё 8 комментариев
274

Мне нужно было сделать (решение в принятом ответе):

git fetch origin
git reset --hard origin/master

Далее следуют:

git clean -f

для удаления локальных файлов

Чтобы узнать, какие файлы будут удалены (без их удаления):

git clean -n -f
  • 69
    также, git clean -d -f если есть неотслеживаемые каталоги.
  • 37
    также git clean -fdx
Показать ещё 8 комментариев
165

Сначала вернемся к ранее извлеченному HEAD соответствующей ветки восходящего направления:

git reset --hard @{u}

Преимущество указания @{u} или его подробной формы @{upstream} заключается в том, что имя удаленного репо и ветки не нужно указывать явно.

Затем, при необходимости, удалите неотслеживаемые файлы, при необходимости также с помощью -x:

git clean -df

Наконец, по мере необходимости, получите последние изменения:

git pull
  • 27
    Это кажется лучшим ответом, чем принятый, потому что он динамически сбрасывается в текущую восходящую ветвь, а не всегда в статический, такой как origin/master
  • 0
    Это самый удобный подход!
101

git reset --hard HEAD фактически только сбрасывается до последнего зафиксированного состояния. В этом случае HEAD ссылается на HEAD вашего ветки.

Если у вас несколько коммитов, это не сработает.

То, что вы, вероятно, захотите сделать, - reset для главы источника или того, что вы называете удаленным репозиторием. Я бы просто сделал что-то вроде

git reset --hard origin/HEAD

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

  • 2
    В моем ответе было неверное предположение, которое Дэн поймал ранее. Я отредактировал это, так как я не хочу никого вводить в заблуждение. Что касается материала origin / master или origin / HEAD, я ожидаю, что это зависит от того, действительно ли вы сначала делаете выборку. Если вы только что клонировали источник, и у него не было других веток, что я нахожу довольно распространенным, тогда он должен сбросить его нормально. Но, конечно, Дэн прав.
58

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

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

git fetch
git reset --hard
git clean -x -d -f

Предупреждение: git clean -x -d -f необратимо, и вы можете потерять файлы и данные (например, вещи, которые вы проигнорировали, используя .gitignore).

  • 12
    Предупреждение: «git clean -x -d -f» необратим, и вы можете потерять файлы и данные в .gitignore
31

Вопрос содержит два вопроса:

  • как reset локальная ветвь до точки, где находится пульт
  • как очистить область промежуточного уровня (и, возможно, рабочий каталог), так что git status говорит nothing to commit, working directory clean.

Одностановочный ответ:

  • git fetch --prune (необязательно) Обновляет локальный снимок удаленного репо. Другие команды только локальные.
    git reset --hard @{upstream} Помещает указатель локальной ветки, где находится моментальный снимок удаленного, а также задает индекс и рабочий каталог файлам этого коммита.
  • git clean -d --force Удаляет ненужные файлы и каталоги, которые мешают git сказать "рабочий каталог чистым".
  • 1
    Синтаксис @{upstream} требует установки upstream, что происходит по умолчанию, если вы используете git checkout <branchname> . - В противном случае замените его на origin/<branchname> .
  • 0
    Добавьте -x в git clean чтобы удалить все, что не входит в коммит (то есть даже файлы, игнорируемые механизмом .gitignore).
22

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

Я также добавил приглашение "вы уверены", и какой-то результат обратной связи

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# AT 2012-11-09
# see http://stackoverflow.com/questions/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
branchname=`git rev-parse --symbolic-full-name --abbrev-ref HEAD`
read -p "Reset branch $branchname to origin (y/n)? "
[ "$REPLY" != "y" ] || 
echo "about to auto-commit any changes"
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
  echo "Creating backup auto-save branch: auto-save-$branchname-at-$timestamp"
  git branch "auto-save-$branchname-at-$timestamp" 
fi
echo "now resetting to origin/$branchname"
git fetch origin
git reset --hard origin/$branchname
  • 3
    Вы можете использовать «git remote», чтобы получить имя удаленного. В некоторых случаях это не будет «происхождение»
12

При условии, что удаленный репозиторий origin, и что вы заинтересованы в branch_name:

git fetch origin
git reset --hard origin/<branch_name>

Кроме того, вы идете для сброса текущей ветки origin в HEAD.

git fetch origin
git reset --hard origin/HEAD

Как это устроено:

git fetch origin загружает последние с удаленного компьютера, не пытаясь объединить или переместить что-либо.

Затем git reset сбрасывает <branch_name> к тому, что вы только что <branch_name>. Опция --hard изменяет все файлы в вашем рабочем дереве в соответствии с файлами в origin/branch_name.

12

Вот script, который автоматизирует то, что предлагает самый популярный ответ... См. https://stackoverflow.com/questions/1628088/reset-local-repository-branch-to-be-just-like-remote-repository-head для улучшенной версии, поддерживающей ветки

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# see https://stackoverflow.com/questions/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
  git branch "auto-save-at-$timestamp" 
fi
git fetch origin
git reset --hard origin/master
11

Я сделал:

git branch -D master
git checkout master

полностью reset ветвь


обратите внимание, что вы должны проверить другую ветку, чтобы удалить требуемую ветку

  • 5
    Вы должны прочитать вопрос еще раз, ничего не влияет на удаленный доступ, кроме настройки на то же самое, что и удаленный, так что вы ничего не должны делать с удаленным, и это помогло в моем случае, а не выше.
  • 0
    Если вы хотите установить его так же, как удаленный, вы должны по крайней мере сделать выборку в какой-то момент, вы не согласны?
Показать ещё 1 комментарий
7

Если у вас была проблема со мной, что вы уже внесли некоторые изменения, но теперь по какой-либо причине вы хотите избавиться от нее, самый быстрый способ - использовать git reset следующим образом:

git reset --hard HEAD~2

У меня было 2 не необходимых фиксации, следовательно, число 2. Вы можете изменить его на свой собственный номер фиксации на reset.

Итак, отвечая на ваш вопрос: если вы заработали 5 бит перед удаленным хранилищем HEAD, вы должны запустить эту команду:

git reset --hard HEAD~5

Обратите внимание, что вы потеряете сделанные вами изменения, поэтому будьте осторожны!

5

Предыдущие ответы предполагают, что ветвь reset является текущей ветвью (выведено). В комментариях OP hap497 пояснил, что ветвь действительно проверена, но это явно не требуется исходным вопросом. Поскольку существует хотя бы один "повторяющийся" вопрос, Reset полностью отнести к состоянию хранилища, который не предполагает, что ветвь проверена, здесь есть альтернатива:

Если ветвь "mybranch" в настоящий момент проверена не, до reset на удаленной ветке "myremote/mybranch", вы можете использовать эту команда низкого уровня:

git update-ref refs/heads/mybranch myremote/mybranch

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

Соблюдайте осторожность при этом, и используйте gitk или аналогичный инструмент, чтобы дважды проверить источник и место назначения. Если вы случайно сделаете это в текущей ветке (и git не поможет вам от этого), вы можете запутаться, потому что новое содержимое ветки не соответствует рабочему дереву, которое не изменилось (исправить, обновить ветвь снова, где он был раньше).

5

Если вы хотите вернуться в состояние HEAD как для рабочего каталога, так и для индекса, вы должны git reset --hard HEAD, а не HEAD^. (Возможно, это была опечатка, точно так же, как одиночная или двойная тире для --hard.)

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

3

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

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

xkcd: Git

1

Это то, что я использовал регулярно:

git fetch upstream master;
git reset --hard upstream/master;
git clean -d --force;

Обратите внимание, что хорошей практикой является не вносить изменения в свой локальный мастер, а вместо этого извлекать изменения в другую ветвь для любого изменения с именем ветки, которому предшествует тип изменения, например, feat/, chore/, fix/ и т.д. Таким образом, вы только нужно вытягивать изменения, а не выдвигать какие-либо изменения у мастера То же самое для других отраслей, которым способствуют другие. Таким образом, вышеприведенное следует использовать только в том случае, если вы зафиксировали изменения в ветке, в которую зафиксированы другие, и вам необходимо выполнить сброс. В противном случае в будущем избегайте нажатия на ветку, к которой другие подталкивают, вместо этого извлекайте и передавайте в указанную ветку через извлеченную ветку.

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

Проверьте свои пульты, убедитесь, что ваш исходящий и исходный код соответствуют вашим ожиданиям, если не так, как ожидалось, используйте git remote add upstream <insert URL>, например, исходный репозиторий GitHub, с которого вы ответили, и/или git remote add origin <insert URL of the forked GitHub repo>.

git remote --verbose

git checkout develop;
git commit -m "Saving work.";
git branch saved-work;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force

На GitHub вы также можете извлекать ветку с тем же именем, что и у локальной, чтобы сохранить там работу, хотя в этом нет необходимости, если у origin development есть те же изменения, что и у локальной ветки сохраненной работы. В качестве примера я использую ветвь разработки, но это может быть любое существующее имя ветки.

git add .
git commit -m "Reset to upstream/develop"
git push --force origin develop

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

git merge -s recursive -X theirs develop

Во время использования

git merge -s recursive -X ours develop

для сохранения конфликтующих изменений branch_name. В противном случае используйте mergetool с git mergetool.

Со всеми изменениями вместе:

git commit -m "Saving work.";
git branch saved-work;
git checkout develop;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force;
git add .;
git commit -m "Reset to upstream/develop";
git push --force origin develop;
git checkout branch_name;
git merge develop;

Обратите внимание, что вместо upstream/development вы могли бы использовать хеш коммита, другое имя ветки и т.д. Используйте инструмент CLI, такой как Oh My Zsh, чтобы проверить, что ваша ветвь имеет зеленый цвет, указывая, что нечего коммитить, а рабочий каталог чистый ( что подтверждается или также подтверждается git status). Обратите внимание, что это может фактически добавить коммиты по сравнению с разработкой в восходящем потоке, если что-то автоматически добавляется коммитом, например, диаграммы UML, заголовки лицензий и т.д., Поэтому в этом случае вы могли бы затем вытащить изменения в origin develop для последующей upstream develop, если необходимо.

0

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

REPO_PATH=$(pwd) && GIT_URL=$(git config --get remote.origin.url) && cd .. && rm -rf $REPO_PATH && git clone --recursive $GIT_URL $REPO_PATH && cd $REPO_PATH

* предполагает, что ваши .git файлы не повреждены

-3

Если вы не против сохранения локальных изменений, но все же хотите обновить свой репозиторий, чтобы он совпал с origin/HEAD, вы можете просто скопировать свои локальные изменения, а затем потянуть:

git stash
git pull
-8

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

git fetch origin
git reset --hard origin/master
  • 0
    Может кто-нибудь сказать мне, что не так с этим, потому что много времени я использую это для сброса моей локальной ветви с удаленным.
  • 1
    Топ ответ уже включает в себя ваш ответ.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню