Скиньте локальну гілку сховища так само, як віддалену HEAD HEAD


3851

Як я можу скинути свою локальну гілку таким же, як гілка у віддаленому сховищі?

Я зробив:

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

Скажіть, будь ласка, чому я змінив це? Я не торкнувся цих файлів? Якщо я це зробив, я хочу їх видалити.


8
За результатами git statusдругої команди git reset --hard HEADне вдалося. Однак ви не вставили його вихід. → Неповне питання.
Роберт Сімер

2
Ви змішуєте дві проблеми тут: 1) як скинути локальну гілку до точки, де знаходиться пульт, і 2) як очистити свою область постановки (і, можливо, робочий каталог), так що це git statusговорить nothing to commit, working directory clean. - Будь ласка уточніть!
Роберт Сімер

Відповіді:


6687

Встановити філію так, щоб вона точно відповідала віддаленій гілці:

git fetch origin
git reset --hard origin/master

Якщо ви хочете зберегти стан поточної філії перед цим (на всякий випадок), ви можете зробити:

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

Тепер ваша робота зберігається на гілці "мій-збережений-робота", якщо ви вирішите, що ви хочете її повернути назад (або хочете переглянути її пізніше або відрізняти її від оновленої гілки).

Зауважте, що перший приклад передбачає, що назва віддаленого репо є "походженням" і що гілка, що має ім'я "master" у віддаленому репо, відповідає поточній реєстраційній гілці вашого місцевого репо.

До речі, ця ситуація, в якій ви знаходитесь, виглядає жахливо, як звичайний випадок, коли було здійснено натиск на перевірену в даний час гілку непрофільного сховища. Ви нещодавно проштовхувалися у місцеве репо? Якщо ні, то не хвилюйтеся - щось інше, можливо, спричинило, що ці файли несподівано змінилися. В іншому випадку слід пам’ятати, що не рекомендується проникати в неоголене сховище (а не в галузь, що перевіряється в даний час).


4
Спасибі за вашу відповідь. Ви сказали: "Зауважте, що перший приклад передбачає, що назва віддаленого репо є" походженням "і що гілка, що має назву" master "у віддаленому репо, відповідає гілці вашого місцевого репо." Як я можу двічі перевірити ім'я віддаленого репо і ім'я моєї гілки, щоб бути впевненим, перш ніж виконати "git reset --hard"? Знову дякую.
hap497

21
Якщо ви прямо не назвали пульт, то його ім’я, ймовірно, просто "походження" (за замовчуванням). Ви можете скористатися "git remote", щоб отримати список усіх віддалених імен. Потім ви можете використовувати "git remote <ім'я>", щоб побачити, які гілки натискають / тягнуть один з одним (наприклад, якщо ваша "головна" гілка була клонована від "master" у віддаленому імені "origin", тоді ви отримаєте рядок що говорить "майстер зливається з віддаленим майстром").
Dan Molding

6
"не рекомендується
занурюватися в неоголене

27
Одразу після отримання, я вважаю, що ви можете зробити це, git reset FETCH_HEAD --hardнатомість, це те саме значення.
Жан

6
Не додав файли, які я додав.
Трисмегістос

416

Мені потрібно було зробити (рішення у прийнятій відповіді):

git fetch origin
git reset --hard origin/master

Далі:

git clean -f

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

Щоб побачити, які файли буде видалено (не фактично їх видаляючи):

git clean -n -f

89
також, git clean -d -fякщо є неперевірені каталоги.
garg

54
такожgit clean -fdx
Swapnil Kotwal

14
Якщо ви хочете точну копію віддаленого відділення, вам слід дотримуватися git clean -ffdx. Зауважте, що thare - це два f.
Трисмегістос

6
Це git clean -fбуло найважливішим твором, який мені потрібен. Дякую!
КГВР

17
будьте обережні, використовуючи команду clean. він може видалити проігноровані файли з інших гілок.
mikoop

307

По-перше, скиньте попередньо отриману HEADвідповідну гілку вище за течією:

git reset --hard @{u}

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

Далі, за необхідності, видаліть незатребувані файли, необов'язково також за допомогою -x:

git clean -df

Нарешті, за необхідності, отримайте останні зміни:

git pull

54
Це здається кращою відповіддю від прийнятої, оскільки вона динамічно скидається на поточну гілку вище за течією, а не завжди на статичну, таку якorigin/master
Jon z

Місце на Jonz увімкнено, @{upstream}це дуже зручно, і його можна використовувати в псевдонімах:alias resetthisbranch="git reset --hard @{upstream}"
Siddhartha

1
@GangadharJannu git reset --hardвимагає виконання зобов’язань, інакше воно не знатиме, до чого скинути вас. @{u}вказує на конкретний вчинок - голову відстежуваної гілки, з того часу, коли ви востаннє робили git fetch.
Крістофер Баккейорд

1
@KristofferBakkejord Дякую за пояснення, але навіть без хеш-файлів ми можемо обійтися, git reset --hardхоча він не
скинеться

3
Для всіх, хто ледь не відкрив тут нове запитання, якщо ви зібралися з Powershell, використовуйте цитати ( git reset --hard "@{u}"). Зайняв мене час, щоб зрозуміти це.
MPStoering

112

git reset --hard HEADфактично скидається лише до останнього скоєного стану. У цьому випадку HEAD відноситься до HEAD вашої філії.

Якщо у вас є кілька комісій, це не працюватиме.

Те, що ви, мабуть, хочете зробити, - скинути в голову походження або все, що називається, віддаленим сховищем. Я, мабуть, просто зробив щось на кшталт

git reset --hard origin/HEAD

Будьте обережні, хоча. Жорсткі скидання не можна легко скасувати. Краще робити так, як пропонує Дан, і відкинути копію змін перед скиданням.


2
У моїй відповіді була неправильна пропозиція, яку Дан спіймав раніше. Я відредагував це далеко, оскільки не хочу когось зводити з оману. Що стосується походження / майстра чи походження / HEAD, я думаю, що це залежить від того, чи ви дійсно спочатку зробите це. Якщо ви просто клонували походження, а у нього не було інших гілок, які, як я вважаю, є досить поширеними, то це має скинути його на чудово. Але, звичайно, Дан має рацію.
Мікаел Олсон

73

Усі вищенаведені припущення є правильними, але часто для того, щоб реально скинути проект, вам також потрібно видалити навіть файли, які є у вашому .gitignore.

Отримати моральний еквівалент стирання каталогу проектів та повторного клонування з віддаленого пристрою:

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

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


12
Попередження: "git clean -x -d -f" є незворотним, і ви можете втратити файли та дані в .gitignore
Akarsh Satija

Трохи коротше: git clean -xdfце дорівнює git clean -x -d -f.
Кирил

мерзотник чистий -ffxd , щоб видалити все не в репо
Трисмегиста

44

Використовуйте команди нижче. Ці команди також видалять усі незафіксовані файли з локального git

git fetch origin
git reset --hard origin/master
git clean -d -f

6
Це більш повна відповідь, оскільки без цього git clean -d -fми все ще матимемо деякі речі старої гілки в локальному каталозі. Спасибі людина.
Флавіо

3
Це те, що АКТУАЛЬНО робить його таким, як віддалений. Чистота важлива.
Девід С.

1
мерзотник чистий -ffxd до воістину видалити всі
Трисмегиста

1
Це саме те, що мені було потрібно. Дякую
AllJs

38

Питання поєднує тут два питання:

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

Єдиною відповіддю є:

  1. git fetch --prune (необов’язково) Оновлення локального знімка віддаленого репо. Подальші команди є лише локальними.
    git reset --hard @{upstream}Встановлює місцевий вказівник гілки на те, де знаходиться знімок пульта, а також встановлює індекс та робочий каталог у файли цього фіксатора.
  2. git clean -d --force Вилучає незатрековані файли та каталоги, які перешкоджають git сказати «чистий робочий каталог».

1
@{upstream}Синтаксис вимагає вгору по течії , щоб бути безліч , яке відбувається за замовчуванням , якщо вам git checkout <branchname>. - Інакше замініть його на origin/<branchname>.
Роберт Сімер

Додати, -xщоб git cleanвидалити все, що не знаходиться у коміті (тобто навіть файли, ігноровані механізмом .gitignore).
Роберт Сімер

22

З цим я стикаюся регулярно, і я узагальнив сценарій Вольфганга, наданий вище, для роботи з будь-якою гілкою

Я також додав підказку "Ви впевнені" та деякі відгуки

#!/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", щоб отримати ім'я віддаленого. У деяких випадках це не буде "походження"
Юрік

17

За умови, що віддалене сховище є 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.


14

Я зробив:

git branch -D master
git checkout master

повністю скинути відділення


Зауважте, вам слід перейти до іншої гілки, щоб мати змогу видалити потрібну гілку


5
Ви повинні ще раз прочитати питання, що нічого не впливає на віддалений, але налаштування так само, як віддалене, тому нічого не потрібно робити з дистанційним, і це допомогло в моєму випадку і не вище.
користувач2846569

Якщо ви хочете встановити його так само, як віддалений, вам слід принаймні зробити якийсь момент, якщо ви не згодні?
Тім

2
вам слід принаймні спробувати це чи прочитати документи: kernel.org/pub/software/scm/git/docs/git-checkout.html
user2846569

До речі, у мене був пошкоджений .pck файл у гілці, а інші варіанти не працювали, дякую !!
LuckyBrain

14

Ось сценарій, який автоматизує те, що пропонує найпопулярніша відповідь ... Дивіться https://stackoverflow.com/a/13308579/1497139 для вдосконаленої версії, яка підтримує гілки

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# see /programming/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

10

Якщо у вас виникли проблеми, як у мене, ви вже вчинили деякі зміни, але тепер, з будь-якої причини ви хочете позбутися від неї, найшвидший спосіб - це використовувати git resetтак:

git reset --hard HEAD~2

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

Отже, відповідаючи на ваше запитання - якщо у вас на 5 позицій попереду віддаленого HEAD-сховища, слід виконати цю команду:

git reset --hard HEAD~5

Зауважте, що ви втратите внесені вами зміни, тому будьте обережні!


7

Попередні відповіді передбачають, що гілка, яку потрібно скинути, є поточною гілкою (відмічена). У коментарях OP hap497 уточнив, що галузь справді перевірена, але це не вимагає прямого запитання в первісному питанні. Оскільки існує щонайменше одне "повторне" запитання, Скинути гілку повністю у стан сховища , що не передбачає перевірку гілки, ось альтернатива:

Якщо гілка "mybranch" наразі не перевірена, щоб скинути її на голову віддаленої гілки "myremote / mybranch", ви можете використовувати цю команду низького рівня :

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

Цей метод залишає перевірену гілку такою, якою вона є, а робоче дерево недоторканою. Він просто пересуває голову мого відділення до іншого зобов'язання, що б не було подано як другий аргумент. Це особливо корисно, якщо кілька відділень потрібно оновити до нових віддалених голів.

Будьте обережні, виконуючи це, і використовуйте gitkчи подібний інструмент для подвійної перевірки джерела та місця призначення. Якщо ви випадково зробите це на поточній гілці (і git не убереже вас від цього), ви можете заплутатися, оскільки новий вміст гілки не відповідає робочому дереву, яке не змінилося (виправити, оновити гілку ще раз, туди, де було раніше).


7

Це те, що я часто використовую:

git fetch upstream develop;
git reset --hard upstream/develop;
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 ви також можете оформити гілку з тим самим іменем, що і місцева, щоб зберегти роботу там, хоча це не обов'язково, якщо розвиток походження має ті самі зміни, що і місцева гілка збереженої роботи. Я використовую галузь розробки як приклад, але це може бути будь-яка існуюча назва гілки.

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, в разі необхідності.


6

Відповідь

git clean -d -f

було недооцінено ( -d для видалення каталогів). Дякую!


І запускайте повну, 100% чисту папку repo без зайвих файлів git clean -xdf. Це видалить будь-які файли, про які не знає git, і змусить вашу папку відповідати тому, що саме в списку об’єктів git. Зауважте, що ви можете додати -n(наприклад git clean -nxdf), щоб виконати "що-якщо", і він підкаже, що воно буде видалено, фактично нічого не роблячи. ( git clean )
qJake

5

Якщо ви хочете повернутися до HEADстану як для робочого каталогу, так і для індексу, тоді вам слід git reset --hard HEAD, а не робити HEAD^. (Це може бути помилка друку, як і сингл проти подвійного тире --hard.)

Що стосується вашого конкретного запитання щодо того, чому ці файли відображаються у статусі зміненого, схоже, можливо, ви зробили м'який перезавантаження замість жорсткого скидання. Це призведе до того, що файли, які були змінені в HEADкомітеті, з’являться так, ніби вони інсценовані, що, ймовірно, ви бачите тут.


4

Ніяка кількість скидання та очищення, здається, не вплинула на відслідковувані та змінені файли в моєму локальному git repo (я спробував усі варіанти, наведені вище). Єдиним моїм рішенням для цього було переправити місцеве репо і повторно клонувати його з пульта.

На щастя, я не мав жодної іншої гілки, про яку я дбав.

xkcd: Git


1

Єдине рішення, яке працює у всіх випадках, які я бачив, - це видалити та повторно запустити. Можливо, є інший шлях, але очевидно, що цей спосіб не залишає шансів залишитися там старої держави, тому я вважаю за краще. 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 не пошкоджені


4
Ви також можете просто перевстановити свою операційну систему, якщо хочете бути впевненими!
Себастьян

1

Ви забули створити функціональну галузь і помилково вчинили майстра?

Ви можете створити гілку функції зараз і встановити головний режим назад, не впливаючи на робоче дерево (локальну файлову систему), щоб уникнути запуску збірок, тестів та неполадок із блокуванням файлів:

git checkout -b feature-branch
git branch -f master origin/master

1

Лише 3 команди змусять його працювати

git fetch origin
git reset --hard origin/HEAD
git clean -f

-3

Якщо ви не заперечуєте над збереженням своїх локальних змін, але все ж хочете оновити сховище так, щоб воно відповідало походженням / HEAD, ви можете просто сховати свої локальні зміни, а потім витягнути

git stash
git pull
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.