Чи втратив я зміни після перебазування?


80

Нещодавно я перебазував гілку, над якою працював. Історія дерева виглядала приблизно так:

1 = 2 = 3 = 4
     \
      5 = 6 = 7
           \
            8

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

git checkout my_branch
git rebase master

<багато git mergetool / git rebase --skip для вирішення конфліктів>

Тільки зараз, коли я біжу:

git checkout my_branch
git diff master

Я отримую нульові різниці. Я не втратив свою гілку (я все ще можу відтворити свої зміни із збереженого патчу), але я не можу знайти злиття / перебазування, яке я зробив. Що я зробив неправильно? Чи перебазування все ще є десь із моїми змінами, об’єднаними з основним, чи мені доведеться це робити ще раз?


2
Коли ви це зробили git rebase --skip(замість --continue), чи можливо ви "пропустили" зміни, які насправді все-таки мали суттєві зміни під час перебазування?
CB Bailey

2
Якщо ви вручну об’єднали, як правило, хочете --continue. Пропускати потрібно лише в тому випадку, якщо результатом об’єднання є "без змін". Скільки змін ви пропустили і скільки насправді застосували?
CB Bailey

14
У мене є нове правило: Без перебазування після 1 години ранку
ryan0

3
Простий спосіб уникнути проблем із перелаштуванням бази - створити гілку перед її запуском. Ви також зможете легше порівняти кінцевий результат із оригіналом. Просто видаліть гілку, коли закінчите.
jpmc26,

2
Це (https: //) goo.gl/YQUyi1 врятувало мій час.
InaFK

Відповіді:


199

Якщо ви не бачите жодної різниці, я підозрюю, що ви втратили зміни. Ви можете скористатись git reflogідентифікацією гілки, яка існувала до перебазування, та використанняgit reset --hard <my-branch-tip-before-rebase> для повернення початкової гілки. І так, вам доведеться знову пройти процес. :-(

Я не зовсім впевнений, як ти опинився з ними однаково, хоча. Я б очікував побачити наступне з командою, яку ви дали:

1 = 2 = 3 = 4              (master)
     \       \
      \       5' = 6' = 8' (my_branch)
       \
        5 = 6 = 7

У цьому випадку вам, мабуть, слід було використовувати rebase --onto:

git rebase --onto master <commit id for 6> my_branch

Це залишило б у вас графік, який виглядав так:

1 = 2 = 3 = 4              (master)
     \       \
      \       8'           (my_branch)
       \
        5 = 6 = 7

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

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

Іноді конфліктів не уникнути, і їх нудно опрацьовувати. Але я підозрюю, що на практиці ви менше стикаєтесь із цією проблемою.

Щоб отримати додаткову інформацію про пересадку змін між гілками, загляньте на сторінку довідки git rebase . Шукайте "rebase --onto". Перший удар повинен потрапити до вас у розділі, присвяченому пересадці змін на іншу гілку.


Ви були праві; Я використав неправильну команду. Мені потрібно було сказати --onto. Зараз я отримав перебазований патч :) (і мені довелося його переробити, але виправити конфлікт вдруге набагато простіше).
Дейв

23
git reset --hard xxxxxврятував мене! Я думав, що все загублено! Навіть git reset xxxxбез --hardне працював!
Хлоя

7
Я бачив щось подібне. Я бачив це на попередній роботі, і побачив це знову сьогодні. Сховище може потрапити в стан, коли звичайний git rebase(проти висхідного) втрачає всі локальні коміти, і просто встановлює головку до вищого. Тоді як a git rebase -iбез змін (все вибрано) працює правильно. Чесно кажучи, це якась незрозуміла помилка.
Райан Ланді,

11
О БОЖЕ МІЙ! Ти врятував мене! Я зробив повторне відбивання, а потім вишню: D
Фернандо Мартінес

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