Двигун Git після примусового оновлення


332

Я просто розчарував деякі вчинки git rebaseі зробив git push --force(що це зло, я знаю).

Тепер інші інженери програмного забезпечення мають іншу історію, і коли вони роблять git pull, Git злиється. Чи є спосіб це виправити, крім виконання rm my-repo; git clone git@example.org:my-repo.git?

Мені потрібно щось на кшталт протилежного git push --force, але git pull --forceне дало намічених результатів.


16
вони можуть видалити свою гілку та створити її теж, не видаляючи цілого репо:git checkout master && git branch -D test && git checkout -b test origin/test
Florian Klein


Відповіді:


509

Для отримання нових комісій

git fetch

Скидання

Ви можете скинути комісію для локальної філії за допомогою git reset.

Щоб змінити комісію місцевої філії:

git reset origin/master --hard

Але будьте обережні, як зазначено в документації:

Скидає індекс і робоче дерево. Будь-які зміни в відслідковуваних файлах у робочому дереві після <commit> відкидаються.

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

База даних

Ви можете відтворювати свої місцеві комітети поверх будь-яких інших комісій / відділень, використовуючи git rebase:

git rebase -i origin/master

Це дозволить викликати ребазування в інтерактивному режимі, де ви можете вибрати, як застосувати кожну окрему комісію, яка відсутня в історії, яку ви відновлюєте поверх.

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

Скористайтеся довідкою git command --helpдля отримання більш детальної інформації та прикладів будь-якої з вищевказаних (або інших) команд.


2
@iblue вибирає між втратою всіх змін, видаленням історії фіксування, але збереженням змін у файлі, або спробою застосувати кожну команду поверх нової заголовки. Найпростіший варіант - це, мабуть, м'яке скидання.
AD7six

1
@iblue Коли ваш колега використовує `git reabse origin / master ', і мається на увазі, поки вони вже мали деякий фіксатор, git напише вашу комісію позаду своєї комісії.
Тім

6
Можливо, варто згадати, що якщо це стосується іншої галузі:git reset origin/otherbranch --hard
bmaupin

Таким чином, щоб уточнити, що це або : Варіант 1: reset --hard, або Варіант 2: reset --soft+ rebase, вірно?
ПлазмаBinturong

2
@PlasmaBinturong № git reset --soft origin/masterзмінить історію фіксації, щоб вона відповідала віддаленим та стадійним відмінностям від віддаленого, який потім буде здійснено . У цьому сценарії не потрібно буде проводити повторне базування даних (і вам це буде заважати через незапущені зміни), оскільки в історії введення комісій немає різниці. Два варіанти скидання або відновлення - не поєднання обох. Будь ласка, задайте питання, чи ваш сценарій відрізняється від того, на який я тут відповів.
AD7six

16

Це не виправить гілки, у яких уже є код, який ви не хочете в них (див. Нижче, як це зробити), але якщо вони витягнули якусь гілку і тепер хочуть, щоб вона була чистою (а не "попереду") походження / деяка галузь), то ви просто:

git checkout some-branch   # where some-branch can be replaced by any other branch
git branch base-branch -D  # where base-branch is the one with the squashed commits
git checkout -b base-branch origin/base-branch  # recreating branch with correct commits

Примітка. Ви можете комбінувати все це, поставивши && між ними

Примітка2: Флоріан згадував про це у коментарі, але хто читає коментарі, шукаючи відповіді?

Примітка3: Якщо у вас забруднені гілки, ви можете створити нові, виходячи з нової "тупої гілки", і просто здійснити вишні.

Наприклад:

git checkout feature-old  # some branch with the extra commits
git log                   # gives commits (write down the id of the ones you want)
git checkout base-branch  # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd   # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch

Тепер особливістю є ваша філія без зайвих (можливо, поганих) зобов’язань!


Це те, що я дуже хотів. Хтось переосмислив головну гілку (бог знає, з якої причини), але у мене не було місцевих змін, які я хотів зробити чи що-небудь. Тож все, що я мав зробити, - це видалити свою місцеву головну гілку (яка почувалася по-справжньому дивною) та зробити замовлення ще раз. Дякую!
Данило Карвальо

@ peter-mortensen Редагування має бути суттєвим відповідно до stackoverflow.com/help/editing
Tom Prats

для останнього кроку ви також можете скористатися git checkout -b base-branch origin/base-branchзgit checkout --track origin/base-branch
bluesmonk

1

Потягніть з базою даних

Звичайний потяг - це витяг + злиття, але те, що ви хочете, - це отримання та відновлення. Це варіант із pullкомандою:

git pull --rebase

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