не може натиснути на відділення після ребатування


131

Ми використовуємо git і маємо головну гілку та гілки розробників. Мені потрібно додати нову функцію, а потім перезавантажити зобов’язання для управління, а потім натиснути на CI-сервер.

Проблема полягає в тому, що якщо у мене виникають конфлікти під час перезавантаження, я не можу натиснути на свою віддалену гілку розробника (на Github) після того, як ребаза буде завершена, поки я не витягну свою віддалену гілку. Це спричиняє повторювані коміти. Коли конфліктів немає, працює так, як очікувалося.

питання: після відновлення бази даних та вирішення конфліктів, як синхронізувати свої локальні та віддалені гілки розробників, не створюючи повторюваних комітетів

Налаштування:

// master branch is the main branch
git checkout master
git checkout -b myNewFeature

// I will work on this at work and at home
git push origin myNewFeature

// work work work on myNewFeature
// master branch has been updated and will conflict with myNewFeature
git pull --rebase origin master

// we have conflicts
// solve conflict
git rebase --continue

//repeat until rebase is complete
git push origin myNewFeature

//ERROR
error: failed to push some refs to 'git@github.com:ariklevy/dropLocker.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

// do what git says and pull
git pull origin myNewFeature

git push origin myNewFeature

// Now I have duplicate commits on the remote branch myNewFeature

EDIT

Так звучить, що це порушить робочий процес:

developer1 працює над myNewFeature developer2, що працює над йогоNewFeature, обидва використовують master як основну гілку

developer2 об'єднує myNewFeature у своюNewFeature

developer1 відновлює, вирішує конфлікти, а потім примушує натиснути на віддалену гілку для myNewFeature

через пару днів developer2 знову об'єднує myNewFeature у своюNewFeature

Чи це змусить інших розробників ненавидіти розробника1?


не рішення, а просто думка. хто we? ти в команді більше, ніж тільки ти? theyскажіть (люди, які знають більше, ніж я), що якщо ви ділитесь своїм кодом, ви не повинні користуватися rebase. Чому ти просто не робиш git pullі git merge?
AdamT

вибачте, ми = команда розвитку
Метт

1
так що так, напевно, не слід надрукувати, коли ви ділитесь кодом. це може призвести до того, що вам доведеться робити такі речі, як перелічене нижче ( forceпоштовх)
AdamT

о, вибачте, коли кажуть rewriting history, що цеrebase
AdamT

За його словами, його галузь розвитку сама, тому це не повинно бути проблемою, якщо хтось не повинен був об'єднати це.
Learath2,

Відповіді:


93

По-перше, ви та ті, з ким ви працюєте, повинні погодитись, тематика / галузь розвитку - це спільна розробка чи лише ваша власна. Інші розробники знають, що не зливатися в моїх галузях розвитку, оскільки вони будуть повернені в будь-який час. Зазвичай робочий процес такий:

o-----o-----o-----o-----o-----o       master
 \
   o-----o-----o                      devel0
                \
                  o-----o-----o       devel1

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

 git fetch origin
 git checkout master
 git merge --ff origin/master

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

Потім, коли в пульті є зміни, і я переадресую до останнього, я перезавантажую:

git checkout devel0
git rebase master
git push -f origin devel0

Інші розробники тоді знають, що їм потрібно буде відновити свої гілки розробок з моїх останніх:

git fetch <remote>
git checkout devel1
git rebase <remote>/devel0

Це призводить до набагато чистої історії:

o-----o                                 master
       \
         o-----o-----o                  devel0
                      \
                        o-----o-----o   devel1

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

Крім того, це здається, що інші розробники можуть робити зобов’язання у ваших відділах розвитку. Ви можете це підтвердити?

Єдиний час для злиття - це коли ваша галузь тем готова прийняти в неї master.

На бічній записці. Якщо кілька розробників займаються одним і тим же сховищем, вам слід розглянути можливість призначення гілок для розрізнення гілок розробників розробників. Наприклад:

git branch 'my-name/devel-branch'

Таким чином, всі тематичні гілки розробників розташовані у власному вкладеному наборі.


1
"Також здається, що інші розробники можуть робити зобов’язання у ваших відділеннях розробок. Чи можете ви це підтвердити?" ТАК вони ...
Метт

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

@Matt Так, ці дві проблеми справді накрутять ваш робочий процес. По-перше, я б повідомив іншим розробникам про те, що тільки власник може взяти на себе зобов’язані розгалужені (наприклад, "matt / devel"). ІМХО, жоден два розробники не повинні брати на себе зобов’язання в одній галузі. Просто створює плутанину. Надалі звільнення та натискання повинні підтримувати два місця в актуальному стані.
Тревор Норріс

Чудова відповідь. У мене є побічне запитання, чому ви використовуєте --forceпрапор, коли це робите git push -f origin devel0?
Нобіта,

2
@Nobita Якщо git pushне вдається перемотати вперед (тобто історія ша не збігається), ви повинні змусити натиснути, щоб перезаписати попередню історію новою історією, створеною з git rebase.
Тревор Норріс

50

Вам потрібно змусити натиснути, коли ви перемістили комірки далі вниз по лінії git очікує, що ви додасте коміти на кінчик гілки. git push -f origin myNewFeatureвиправить вашу проблему.

Порада: вище - законне використання сили натискання. Ніколи не переписуйте історію на загальнодоступному сховищі, або багато людей будуть ненавидіти вас.


1
Я вважаю це найбільш оптимальним способом підтримки робочого процесу.
Syed Priom

1
Дякую, друже. Я використовував цю команду, щоб примусити свою відновлювану локальну гілку до тієї ж віддаленої гілки.
Вей

11
використання git push --force-with-leaseнабагато безпечніше, ніж використанняgit push --force

git push --force-with-lease origin HEAD- якщо припустити, що ваша цільова гілка вже зареєстрована
Lucici Sergiu

31

Тут головне пам’ятати - те, що відбувається за допомогою кулісу та реставрації.

Потяг, в основному, робить дві речі: витягнення та злиття. Якщо ви включите --rebase, він зробить ребазу замість злиття.

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

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

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

Це вимагатиме від вас періодично натискати змінені зміни або використовуючи силу:

git push -f origin newfeature

Або в деяких випадках ваш адміністратор, можливо, вилучив можливість примусового застосування, тому ви повинні видалити та відтворити:

git push origin :newfeature
git push origin newfeature

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

Пам'ятайте, що майже завжди можна відмовитися від GC в GC, скориставшись:

git reflog

Це ВЕЛИЧЕЗНА ЕКОЛОГІЯ життя, оскільки ви можете повернутись до стабільнішого стану, якщо ви загубитесь у всіх своїх базах управління / конфліктів.


Наведений вище варіант видалення та відтворення непогано працював. На мою репо не допускається жодне змушування!
Саймон Холмс

2

Потрібно виконати вимушений поштовх, тобто git push -f origin myNewFeature

О, і вам краще переконатися, що люди нічого не базують на вашому відділенні розробників - зазвичай ви не повинні публікувати гілки, де ви переписуєте історію взагалі (а точніше, не переписуйте історію після опублікування). Один із способів - це використання назви гілки типу, wip/myNewFeatureа потім згадування про те, що wipгілки час від часу будуть переобладнані.


використання git push --force-with-leaseнабагато безпечніше, ніж використанняgit push --force

@MrCholo Люди не почнуть використовувати це, поки git не додасть для нього короткий варіант, як -fдля звичайного примусового натискання :)
ThiefMaster

га так, я використав це в автоматизованому скрипті

2

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

Якщо ми припустимо , що ви збираєтеся використовувати git pull --rebase ...(або деяка зміна на цьому) з подальшим силовим поштовхом до віддаленої гілки, потім що порушує робочий процес в вашому прикладі developer2 вливається myNewFeatureв hisNewFeature. Має сенс мати можливість відновити свою власну гілку функцій, доки ніхто інший не працює над цією гілкою, тому вам потрібні правила для розмежування території гілки.

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

Я вважаю, що це можна вважати спрощеною версією робочого процесу Gitflow.


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