Сбросить ветку локального репозитория так, чтобы она была похожа на заголовок удаленного репозитория
Как мне переустановить локальную ветку так, чтобы она была похожа на ветку в удаленном репозитории?
Я сделал:
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
Скажите, пожалуйста, почему у меня есть эти "модификации"? Я не трогал эти файлы? Если я это сделаю, я хочу удалить их.
18 ответов
Настройка ветки в точном соответствии с удаленной веткой может быть выполнена в два этапа:
git fetch origin
git reset --hard origin/master
Если вы хотите сохранить текущее состояние вашей ветви перед этим (на всякий случай), вы можете сделать следующее:
git commit -a -m "Saving my work, just in case"
git branch my-saved-work
Теперь ваша работа сохраняется в ветке "my-save-work" на тот случай, если вы решите, что хотите вернуть ее (или хотите посмотреть на нее позже или сравнить ее с обновленной веткой).
Обратите внимание, что в первом примере предполагается, что имя удаленного репо - "origin", и что ветвь с именем "master" в удаленном репо соответствует текущей извлеченной ветке в вашем локальном репо.
Кстати, эта ситуация, в которой вы находитесь, очень похожа на обычный случай, когда в текущую извлеченную ветвь непрошедшего репозитория была сделана загрузка. Вы недавно продвигались в свой локальный репо? Если нет, то не стоит беспокоиться - что-то еще должно было привести к изменению этих файлов. В противном случае вы должны знать, что не рекомендуется загружать в не-пустой репозиторий (и, в частности, не в извлеченную в данный момент ветку).
Мне нужно было сделать (решение в принятом ответе):
git fetch origin
git reset --hard origin/master
Далее следуют:
git clean -f
Чтобы увидеть, какие файлы будут удалены (без их фактического удаления):
git clean -n -f
Сначала вернемся к ранее извлеченному HEAD
соответствующей ветви вверх по течению:
git reset --hard @{u}
Преимущество указания @{u}
или его подробной формы @{upstream}
заключается в том, что имя удаленного репо и филиала не нужно указывать явно.
Затем при необходимости удалите неотслеживаемые файлы, при необходимости также с помощью -x
:
git clean -df
Наконец, по мере необходимости, получите последние изменения:
git pull
git reset --hard HEAD
фактически сбрасывается только до последнего зафиксированного состояния. В этом случае HEAD означает HEAD вашей ветки.
Если у вас есть несколько коммитов, это не сработает ..
То, что вы, вероятно, захотите сделать, - это сбросить на исходную точку или как называется ваш удаленный репозиторий. Я бы, наверное, просто сделал что-то вроде
git reset --hard origin/HEAD
Будьте осторожны, хотя. Жесткий сброс не может быть легко отменен. Лучше сделать, как предлагает Дэн, и перед сбросом ответвьте копию ваших изменений.
Все вышеперечисленные предложения верны, но часто для действительно сброса вашего проекта вам также необходимо удалить даже файлы, которые есть в вашем .gitignore
.
Чтобы получить моральный эквивалент удаления каталога проектов и повторного клонирования с пульта дистанционного управления, выполните следующие действия:
git fetch
git reset --hard
git clean -x -d -f
Предупреждение : git clean -x -d -f
является необратимым , и вы можете потерять файлы и данные (например, вещи, которые вы проигнорировали, используя .gitignore
).
Вопрос смешивает две проблемы:
- как сбросить локальную ветвь до точки, где удаленный находится
- как очистить вашу промежуточную область (и, возможно, рабочий каталог), чтобы
git status
сказалnothing to commit, working directory clean.
Единый ответ:
-
git fetch --prune
(необязательно) Обновляет локальный снимок удаленного репо. Другие команды являются только локальными.git reset --hard @{upstream}
Размещает указатель локальной ветви где находится снимок удаленного компьютера, а также установите индекс и рабочий каталог для файлов этого коммита. -
git clean -d --force
Удаляет неотслеживаемые файлы и каталоги, которые мешают git сказать «очистить рабочий каталог». к югу>
С этим я регулярно сталкиваюсь, & Я обобщил приведенный выше скрипт Вольфганга для работы с любой веткой
Я также добавил приглашение "Вы уверены?" & некоторый вывод обратной связи
#!/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
Вот скрипт, который автоматизирует то, что предлагает самый популярный ответ ... См. https://stackoverflow.com/a/13308579/1497139 для улучшенной версии, которая поддерживает ветви
#!/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
При условии, что удаленный репозиторий является 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>
Ветка на то, что вы только что забрали. Параметр --hard
изменяет все файлы в рабочем дереве в соответствии с файлами в origin/branch_name
.
Я сделал:
git branch -D master
git checkout master
чтобы полностью сбросить ветку
обратите внимание, вы должны оформить заказ в другую ветку, чтобы иметь возможность удалить нужную ветку
Если у вас возникла проблема со мной, что вы уже совершили некоторые изменения, но теперь по любой причине вы хотите от нее избавиться, самый быстрый способ - использовать git reset
вот так:
git reset --hard HEAD~2
У меня было 2 неиспользуемых коммита, отсюда и номер 2. Вы можете изменить его на свое количество коммитов для сброса.
Итак, отвечая на ваш вопрос - если вы на 5 коммитов впереди HEAD удаленного репозитория, вам нужно выполнить эту команду:
git reset --hard HEAD~5
Обратите внимание, что вы потеряете внесенные изменения, поэтому будьте осторожны!
Если вы хотите вернуться в состояние HEAD
как для рабочего каталога, так и для индекса, то вам следует git reset --hard HEAD
, а не HEAD^
. (Это может быть опечатка, точно так же как одинарная или двойная черта для --hard
.)
Что касается вашего конкретного вопроса относительно того, почему эти файлы появляются в статусе измененного, похоже, что вы сделали программный сброс вместо аппаратного сброса. Это приведет к тому, что файлы, которые были изменены в коммите HEAD
, будут выглядеть так, как если бы они были размещены, что, скорее всего, то, что вы видите здесь.
Предыдущие ответы предполагают, что ветвь, которая будет сброшена, является текущей веткой (извлечено). В комментариях OP hap497 пояснил, что ветвь действительно проверена, но это не требуется явно в исходном вопросе. Поскольку есть хотя бы один «дублирующий» вопрос, полностью сбросьте ветвь в состояние хранилища , который не предполагает, что ветвь извлечена, вот альтернатива:
Если ветвь "mybranch" в данный момент не извлечена, чтобы сбросить ее в голову удаленной ветки "myremote /mybranch", вы можете использовать этот команда низкого уровня :
git update-ref refs/heads/mybranch myremote/mybranch
Этот метод оставляет извлеченную ветвь такой, какая она есть, и рабочее дерево нетронутым. Он просто перемещает голову mybranch на другой коммит, независимо от того, что указано в качестве второго аргумента. Это особенно полезно, если необходимо обновить несколько веток до новых удаленных голов.
При этом соблюдайте осторожность и используйте gitk
или аналогичный инструмент для двойной проверки источника и места назначения. Если вы случайно сделаете это в текущей ветке (и git не будет вас об этом предупреждать), вы можете запутаться, потому что новое содержимое ветки не соответствует рабочему дереву, которое не изменилось (чтобы исправить, снова обновите ветку, туда, где это было раньше).
Похоже, что никакие сброса и очистки не оказали никакого влияния на неотслеживаемые и измененные файлы в моем локальном git-репо (я пробовал все варианты выше). Мое единственное решение для этого состояло в том, чтобы восстановить локальное хранилище и повторно клонировать его с пульта.
К счастью, у меня не было других ветвей, о которых я заботился.
Это то, что я использовал регулярно, хотя и для других веток:
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
, чтобы сохранить конфликтующие изменения имени_в ветви. В противном случае используйте 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
, если необходимо.
Единственное решение, которое работает во всех случаях, которые я видел, это удалить и откинуть. Может быть, есть другой путь, но, очевидно, этот путь не оставляет шансов на то, что старое государство останется там, поэтому я предпочитаю это. Bash one-liner вы можете установить как макрос, если вы часто путаетесь в 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 не повреждены
Если вы не возражаете против сохранения локальных изменений, но все же хотите обновить репозиторий, чтобы он соответствовал origin /HEAD, вы можете просто сохранить локальные изменения и затем нажать:
git stash
git pull
Если вы хотите, чтобы текущие изменения использовались позже, то сохраните изменения, в противном случае вы можете использовать эти две команды,
git fetch origin
git reset --hard origin/master