переміщення, здійснене (але не натиснене) змінюється на нову гілку після витягування


460

Я проробив неабияку роботу ("Ваша філія випереджає" походження / головний "на 37 комітетів."), Яка справді повинна була перейти в свою власну гілку, а не в master. Ці зобов’язання існують лише на моїй локальній машині, і на мене не підштовхували origin, але ситуація дещо ускладнюється тим, що інші дияволи підштовхували, origin/masterі я змінив ці зміни.

Як я зворотним чином переміщу свої 37 місцевих комісій на нову гілку? На підставі документів виходить, що git rebase --onto my-new-branch masterабо ...origin/masterслід це зробити, але обидва просто дають мені помилку "фатально: Потрібна одна редакція". man git-rebaseнічого не говорить про надання перегляду rebaseта його прикладів цього не роблять, тому я не знаю, як вирішити цю помилку.

(Зауважте, що це не дублікат Переміщення існуючої, невпорядкованої роботи до нової гілки в Git або Як об'єднати мої локальні неприйняті зміни в іншу гітку Git? Оскільки ці питання стосуються невмілих змін у локальному робочому дереві, а не змін, які мають вчинено на місцях.)


Перевірте це рішення . Здається, це легко і чисто.
Тоні

Перевірте це рішення . Здається, це легко і чисто.
Тоні

Відповіді:


518

Це має бути добре, оскільки ви ще не переносили свої зобов’язання ніде, і ви можете переписати історію своєї філії після цього origin/master. По-перше, я б запустив, git fetch originщоб переконатися, що origin/masterце актуально. Припускаючи, що ви зараз перебуваєте master, ви повинні мати можливість:

git rebase origin/master

... що відтворить усі ваші зобов’язання, які не origin/masterвкладаються origin/master. За замовчуванням дія бази даних - ігнорування комірок злиття (наприклад, тих, які ваш git pullімовірно введено), і вона просто спробує застосувати патч, введений кожним із ваших комісій origin/master. (Можливо, вам доведеться вирішити деякі конфлікти по дорозі.) Тоді ви можете створити свою нову гілку на основі результату:

git branch new-work

... а потім відновіть masterспину до origin/master:

# Use with care - make sure "git status" is clean and you're still on master:
git reset --hard origin/master

При виконанні такого роду маніпулювання гілок з git branch, git resetі так далі Я вважаю , це корисно часто дивитися на Комміт граф gitk --allабо подібний інструмент, просто щоб переконатися , що я розумію , де все різні рефов вказують.

Крім того, ви могли б просто створити галузь теми, залежно від того, де знаходиться ваш господар в першу чергу ( git branch new-work-including-merges), а потім скинути, masterяк зазначено вище. Однак, оскільки у вашій тематичній гілці будуть включені злиття origin/masterта ви ще не натиснули свої зміни, я б запропонував зробити перезавантаження, щоб історія була охайнішою. (Крім того, коли ви з часом об'єднаєте свою тему гілки назад до основної, зміни будуть більш очевидними.)


8
@Olie: Ні, відповідь правильна під припущеннями у питанні та тими, які я виклав у верхній частині відповіді. Коміти, які мають бути на окремій новій гілці, вже є master; ребаза переписує masterгілку так, щоб нові коміти лінійно були зверху origin/master, а потім git branch new-workстворює new-workгілку, що вказує на кінчик master(поточної гілки), не перемикаючи поточну гілку на new-work. Тож тепер new-workмістяться всі нові коміти. Потім скидання переміщує поточну гілку (ще master) назад до origin/master.
Марк Лонгейр

1
@Quintesse: Мені дуже шкода, якщо ви втратили роботу, але впевнений, що ця відповідь правильна для ситуації, описаної першим запитувачем. (Я щойно відповів на зауваження Олі, сподіваючись уточнюючи.) У будь-якому випадку, на всякий випадок, якщо це допоможе повернути вашу роботу, я повинен сказати, що якщо ваша робота була здійснена протягом останніх кількох днів (одне з припущень у цьому питанні та відповіді ) ви можете легко отримати його за допомогою git reflog.
Марк Лонгейр

5
@Olie: можливо, кращий спосіб пояснити: гілки в git - це як мітки, які вказують на певний коміт; вони автоматично переміщуються до нових комітетів, якщо ви створюєте їх у тій гілці, або їх можна переміщувати git resetіншими способами. Це git branch new-workпросто приказка "створити гілку, що вказує на цю команду, поки я залишаюсь на своїй поточній гілці (яка є головним у цьому випадку)". Тому немає необхідності мати команду, яка переміщує коміти з головного в нову гілку - ви просто створите нову гілку там, і коли ви скинете майстер, нова гілка залишається там, де був майстер
Марк Лонгейр

1
трохи запізнюється на вечірку, але @Olie, тільки те, що статус git, коли на новій гілці не відображаються зобов’язання перед майстром, не означає, що їх насправді немає (припустимо, що саме тому ви переживали). Спробуйте підштовхнути нову гілку до походження: ви побачите, що комісії там є
Фелікс Ганьон-Греньє,

2
@ FélixGagnon-Grenier, не хвилюйся про "запізнення" - завжди є люди, які шукають старі питання, і кожне уточнення допомагає. Дякую! :)
Olie

148

Якщо у вас є невелика кількість комісій, і вам не байдуже, чи поєднуються вони в одну мега-комісію, це працює добре і не так страшно, як робити git rebase:

видалити файли (замінити 1 на # комітів)

git reset --soft HEAD~1

створити нове відділення

git checkout -b NewBranchName

додати зміни

git add -A

взяти на себе зобов’язання

git commit -m "Whatever"

5
Щоб показати легко зрозумілий графік, будь ласка, використовуйте git log --all --decorate --oneline --graph.
EliuX

Ей, @EliuX - я тут не вистачаю релевантності. Чи можете ви розширити?
Стаху

Це щось корисне, щоб перевірити, чи отримали ви
бажаний

4
Дякую тобі!! це дуже просте рішення, і воно спрацювало чудово !!
Кріс Сім

90

Я затримався з тим же питанням. Я знайшов найпростіше рішення, яким мені подобається поділитися.

1) Створіть нову гілку зі своїми змінами.

git checkout -b mybranch

2) (Необов’язково) Натисніть новий код філії на віддалений сервер.

git push origin mybranch

3) Оформити замовлення назад до головного відділення.

git checkout master

4) Скиньте головний код відділення за допомогою віддаленого сервера та видаліть локальну комісію.

git reset --hard origin/master

10
Це дійсно найпростіший шлях
1818 року

4
Ви можете пропустити крок 2. Я припускаю, що за час з початку відповіді git змінився, і ця процедура раніше не була дозволена.
Себастьян

Це найкраща відповідь на мій погляд.
Macindows

1
Цю відповідь потрібно перенести до вершини. Дякую.
Аміт

27

Ще один спосіб припустити, що галузь1 - це гілка з допущеними змінами гілка2 - бажана галузь

git fetch && git checkout branch1
git log

виберіть ідентифікатор фіксації, який потрібно перемістити

git fetch && git checkout branch2
git cherry-pick commit_id_first..commit_id_last
git push

Тепер поверніть незапущені комісії з початкової гілки

git fetch && git checkout branch1
git reset --soft HEAD~1

5
Cherry-pick - це справді найкраща команда "копіювати / переміщувати єдиний фіксатор", особливо коли історія є багажем для ваших цілей.
Джон Нойгаус

Це поки що найзручніша відповідь на питання. Дякую за команду!
Фарах

чи можете ви оновити свій останній коментар, де 1 або n - це кількість незапущених комітетів? Це все-таки дійсно вдале рішення цього питання.
chAlexey

9

Крім того, відразу після того, як ви зробите неправильну гілку, виконайте наступні дії

  1. git log
  2. git diff {previous to last commit} {latest commit} > your_changes.patch
  3. git reset --hard origin/{your current branch}
  4. git checkout -b {new branch}
  5. git apply your_changes.patch

Я можу собі уявити, що існує більш простий підхід для кроків один і два.


6

А як на рахунок:

  1. Відділення від поточної ГОЛОВИ.
  2. Переконайтеся, що ви перебуваєте на майстрі , а не на своїй новій гілці.
  3. git reset повернутися до останнього зобов’язання перед тим, як ви почали вносити зміни.
  4. git pull щоб повторно витягнути лише віддалені зміни, які ви скинули зі скиданням.

Або це вибухне, коли ви спробуєте знову об'єднати гілку?


2
А, це в основному варіант B, описаний @ Mark-Longair вище
Тім Кітінг

2

Ось набагато простіший спосіб:

  1. Створіть нове відділення

  2. На вашій новій гілці зробіть git merge master- це об'єднає ваші здійснені (не натиснуті) зміни до вашої нової гілки

  3. Видалити локальну головну гілку git branch -D masterВикористовуйте -Dзамість того, -dщо ви хочете примусити видалити гілку.

  4. Просто зробіть git fetchна своїй головній гілці і зробіть git pullна своїй головній гілці, щоб переконатися, що у вас є останній код ваших команд.


1

Простіший підхід, який я використовував (припускаючи, що ви хочете перемістити 4 коміти):

git format-patch HEAD~4

(Подивіться в каталог, з якого ви виконали останню команду для 4-х .patchфайлів)

git reset HEAD~4 --hard

git checkout -b tmp/my-new-branch

Тоді:

git apply /path/to/patch.patch

У будь-якому порядку, який ви хотіли.


0
  1. Отримайте свіжу копію своїх джерел

    git clone ........

  2. Зробіть гілку з потрібного положення

    git checkout {position} git checkout -b {branch-name}

  3. Додайте віддалений сховище

    git remote add shared ../{original sources location}.git

  4. Отримайте віддалені джерела

    git fetch shared

  5. Оформити бажану гілку

    git checkout {branch-name}

  6. Об'єднання джерел

    git merge shared/{original branch from shared repository}


0

Для мене це був найкращий спосіб:

  1. Перевірте зміни та злиття конфліктів git fetch
  2. Створіть нову гілку git branch my-changesта натисніть на віддалений
  3. Перехід до нової створеної гілки git master -u upstream-branch remotes/origin/my-changes
  4. Перемістіть свої зобов’язання до нової гілки вище за течією.
  5. Перейти назад до попереднього вище за течією git branch master --set-upstream-to remotes/origin/master
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.