Сбросить ветку локального репозитория, чтобы она была похожа на заголовок удаленного репозитория - PullRequest
3156 голосов
/ 27 октября 2009

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

Я сделал:

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

Подскажите, пожалуйста, почему у меня есть эти «модифицированные»? Я не трогал эти файлы? Если я это сделаю, я хочу удалить их.

Ответы [ 19 ]

8 голосов
/ 16 июня 2014

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

git reset --hard HEAD~2

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

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

git reset --hard HEAD~5

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

6 голосов
/ 26 апреля 2018

Это то, что я часто использую:

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.

5 голосов
/ 25 июня 2016

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

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

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

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

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

5 голосов
/ 27 октября 2009

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

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

3 голосов
/ 22 марта 2019

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

git fetch origin
git reset --hard origin/master
git clean -d -f
3 голосов
/ 01 декабря 2016

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

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

xkcd: Git

0 голосов
/ 14 сентября 2017

Единственное решение, которое работает во всех случаях, которые я видел, это удалить и откинуть. Может быть, есть другой путь, но, очевидно, этот путь не оставляет шансов на то, что старое государство останется там, поэтому я предпочитаю это. 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 не повреждены

0 голосов
/ 04 ноября 2014

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

git fetch origin
git reset --hard origin/master
0 голосов
/ 10 сентября 2014

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

git stash
git pull
...