Як я "перезаписую" гілку на іншій гілці в Git?


257

У мене дві гілки, emailі staging. stagingє останньою, і мені більше не потрібні старі зміни у emailвідділенні, але я не хочу їх видаляти.

Тому я просто хочу скинути весь вміст stagingна emailтак, щоб вони обоє вказували на одне і те саме. Це можливо?


Відповіді:


196

Ви можете використовувати "нашу" стратегію злиття:

$ git checkout staging
$ git merge -s ours email # Merge branches, but use our branch head

26
Я спробував це, і мені здається, що це назад? Це не скидає вміст електронної пошти в постановку, а не навпаки?
Макс

27
@Max У мене була така ж плутанина, і це доставило мені багато клопоту. Вам потрібно виконати цю команду з нової гілки (інсценізація), а потім виконати звичайне злиття / PR зі старою гілкою (електронною поштою).
MrGlass

7
Чому ;в кінці кожної команди? Я обійшвся без ;і, здається, працює. Крім того, ця відповідь є неповною, третім кроком є ​​перевірка старої гілки (електронної пошти), а потім знову об'єднання з інсценізацією.
Росді Касім

4
git rebase -s theirs <oldbranc> <newbranch> працює також (незалежно від того, в якій галузі ви знаходитесь). Зауважте, що в базі даних "їхнє" - це фактично нова галузь, оскільки "наша" є головою, до якої ми зараз застосовуємо зобов'язання.
Рольф

4
@Rolf: але база даних позбудеться інформації про злиття та вирівняє історію. Не обов’язково те, за чим ви хочете. Також не гарна ідея, якщо ви працюєте з уже опублікованою історією.
вязання

99

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

$ git checkout email
$ git tag old-email-branch
$ git reset --hard staging

Ви також можете перезавантажити гілку "Постановка" на гілку "Електронна пошта". Але результат буде містити модифікацію двох гілок.


1
ви, напевно, маєте на увазі git checkout, git checkне існує моїх відомостей
knittl

4
Ви маєте рацію, я так звик до вкладки завершення команди git, що я завжди пишу "git check <TAB>", щоб писати "git checkout"! Виправлено.
Sylvain Defresne

16
git reset порушує репо-репутацію інших людей, які клонували ваше репо
Джеффрі Де Смет,

Я вважаю, що це правильна відповідь. emailГолова відділення повинен просто вказувати на одного голову, stagingі вони обидва матимуть однакові зобов'язання, однакову історію.
cicerocamargo

76

Я бачив кілька відповідей, і це єдина процедура, яка дозволила мені це виправити без будь-яких конфліктів.

Якщо ви хочете, щоб усі зміни з гілки_нау у гілки_ладу, то:

git checkout branch_new
git merge -s ours branch_old
git checkout branch_old
git merge branch_new

одного разу застосувавши ці чотири команди, ви можете без проблем натиснути гілку_old


5
Ваша відповідь справді найкраще відповідає моїй проблемі, оскільки я не хотів скидати HEAD, просто констатуйте перевагу для нових файлів у новій гілці, коли об’єднуєте речі зі старими та працювали без проблем! +1
печі

Я натиснув свою гілку_new на віддалений після "нашого злиття", і цей метод працював на мене. Чи потрібно було мені штовхнути? Або воно б спрацювало без? (Не був впевнений, чи буде він використовувати локальну гілку чи віддалений). Дякую!
aspergillusOryzae

Чому ви не можете просто зробити наступне? мерзотник контроль branch_old мерзотник злиття -s їхній branch_new Clue , взятий з stackoverflow.com/questions/14275856 / ...
Ripu Даман

У ньому сказано, що не вдалося знайти стратегію злиття «свою».
arango_86

Для мене прекрасно працює, має перевагу в тому, що нічого не скидати
Ромен

68

Інші відповіді дали мені правильні підказки, але вони не повністю допомогли.

Ось що для мене спрацювало:

$ git checkout email
$ git tag old-email-branch # This is optional
$ git reset --hard staging
$
$ # Using a custom commit message for the merge below
$ git merge -m 'Merge -s our where _ours_ is the branch staging' -s ours origin/email
$ git push origin email

Без четвертого кроку злиття з нашою стратегією, поштовх вважається нешвидким оновленням вперед і буде відхилено (GitHub).


Це робить повідомлення про злиття-фіксування неправильним, але так, воно чудово працює.
cdunn2001

cdunn2001, мені цікаво. Що було повідомлення про злиття, яке ви очікували, і як це зіпсувалося з цим?
Шям Хабаракада

Там написано "Об’єднати відділення віддаленого відстеження" походження / електронна пошта "в електронну пошту". Тут не згадується інсценізація. Хоча нічого великого. Просто внесіть зміни до комісії або скористайтеся merge -m 'This is not my beautiful house.' -s ours origin/email.
cdunn2001

@ShyamHabarakada, я роблю, як ви кажете, і я отримую проблему щодо нешвидшого оновлення вперед. тому що нічого не відбувається, коли я роблю 4-й крок.
kommradHomer

Четвертий крок вимагає використання джерела / електронної пошти, він не працює лише з локальною електронною поштою.
Тревіс Редер

45

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

git checkout email
git reset --hard staging
git push origin email --force

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


1
електронна пошта git push origin --force не працювала для мене, оскільки в Step2 залишилися гілки розбіжними. Тож після Step2 це те, що я зробив: git reset origin / email, а потім git push
user3505394

2
Саме про це і задавали питання - "як перезаписати, а не злити". Слід прийняти відповідь.
jozols

17

Я хотів об'єднати дві гілки, щоб увесь вміст old_branchоновлювався вмістом відnew_branch

Для мене це спрацювало як шарм:

$ git checkout new_branch
$ git merge -m 'merge message' -s ours origin/old_branch
$ git checkout old_branch
$ git merge new_branch
$ git push origin old_branch

10

Як щодо:

git branch -D email
git checkout staging
git checkout -b email
git push origin email --force-with-lease

@emptywalls, оскільки він робить силовий натиск, не попереджаючи користувача про те, що він може бути відхилений сервером, а також не пояснює, чому це потрібно. Однак це є життєздатним варіантом проекту для одного розробника
David Costa

@DavidCosta, чому це буде відхилено сервером? це проста гілка видалення електронної пошти та копіювання постановки на електронну пошту "... Тому я просто хочу скинути весь вміст" інсценізації "в" електронну пошту ", щоб вони обоє вказували на один і той самий комітет" - саме так і відбувається тут.
Арек С

@ArekS це може бути відмовлено гаком на стороні сервера, якщо гілка встановлена ​​як "захищена", наприклад, у GitLab. Проблема полягає в тому, що якщо хтось інший отримав свою гілку з електронної пошти перед цією операцією, а потім намагається натиснути, посилання більше не збігаються (тому що деякі зобов’язання просто зникають)
David Costa

1
Я редагував оригінал від --force to --force-with-lease, що робить трюк неруйнівним способом.
frandroid

1
Це найкращий спосіб, якщо ви просто хочете здути гілку і почати її очищати від вихідної гілки.
Шейн

6

Інші відповіді виглядали неповними.
Я спробував нижче в повному обсязі, і це спрацювало чудово.

ПРИМІТКА:
1. Зробіть копію свого сховища, перш ніж спробувати нижче, щоб бути в безпечній стороні.

Деталі:
1. Вся розробка відбувається у відділенні розробки
2. гілка qa - це саме та сама копія dev
3. Час від часу код dev потрібно перемістити / перезаписати у гілку qa

тому нам потрібно перезаписати гілку qa, з dev гілки

Частина 1:
З командами нижче, старий qa було оновлено до новішої версії:

git checkout dev
git merge -s ours qa
git checkout qa
git merge dev
git push

Автоматичний коментар для останнього натискання подано нижче:

// Output:
//  *<MYNAME> Merge branch 'qa' into dev,*  

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

Частина 2:

Нижче є несподівані, нові місцеві поступки в розробника, непотрібні,
тому нам потрібно викинути і зробити дев нетронутим.

git checkout dev

// Output:
//  Switched to branch 'dev'  
//  Your branch is ahead of 'origin/dev' by 15 commits.  
//  (use "git push" to publish your local commits)


git reset --hard origin/dev  

//  Now we threw away the unexpected commits

Частина 3:
Перевірте все, як очікувалося:

git status  

// Output:
//  *On branch dev  
//  Your branch is up-to-date with 'origin/dev'.  
//  nothing to commit, working tree clean*  

Це все.
1. старий qa тепер замінений новим кодом відділення Dev
2. локальний чистий (віддалене походження / dev не торкається)


6

Найпростіший спосіб зробити це:

//the branch you want to overwrite
git checkout email 

//reset to the new branch
git reset --hard origin/staging

// push to remote
git push -f

Тепер відділення електронної пошти та інсценізація однакові.


2
Попередження. Це видаляє всі комісії у emailгілці. Це як видалити emailгілку та створити її заново на чолі stagingгілки.
Камерон Хадсон

2
git checkout email
git merge -m "Making email same as staging disregarding any conflicts from email in the process" -s recursive -X theirs staging

1
Ця відповідь була б мені зрозумілішою, якби коментар був зроблений окремо від об'єднання коментаря в команді. Поясніть коротко, що робить -X і як це впливає на це злиття. Спасибі, хоча.
Змусив

@noelicus дякую за коментар, і ви маєте рацію. Я можу змінити відповідь у майбутньому.
Вілла

0

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

git checkout new -b tmp
git merge -s ours old -m 'irrelevant'
git checkout old
git merge --squash tmp
git branch -D tmp
#do any other stuff you want
git add -A; git commit -m 'foo' #commit (or however you like)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.