Як розім’яти твори в git після того, як їх натиснули?


550

Це дає хороше пояснення розбивання кількох комітів:

http://git-scm.com/book/en/Git-Branching-Rebasing

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

EDIT: Коли я це роблю git rebase -i origin/master~4 master, зберігаю перший як pick, встановлюю інші три як squash, а потім виходжу (через cx cc в emacs), я отримую:

$ git rebase -i origin/master~4 master
# Not currently on any branch.
nothing to commit (working directory clean)

Could not apply 2f40e2c... Revert "issue 4427: bpf device permission change option added"
$ git rebase -i origin/master~4 master
Interactive rebase already started

де 2f40 - коміт pick. І тепер жоден із 4 комітетів не відображається в git log. Я очікував, що мій редактор буде перезапущений, щоб я міг ввести повідомлення про фіксацію. Що я роблю неправильно?

Відповіді:


779

Сквош здійснює місцево

git rebase -i origin/master~4 master

а потім натисніть на

git push origin +master

Різниця між --forceі+

З документації git push:

Зверніть увагу, що --forceзастосовується до всіх виправлених посилань, отже, використовуючи їх із push.defaultвстановленим набором matchingабо з декількома націленими адресами, налаштованими на, remote.*.pushможна перезаписати рефери, відмінні від поточної гілки (включаючи локальні, які суворо відстають від віддаленого аналога). Щоб натиснути лише на одну гілку, використовуйте a + перед рефлексу, щоб натиснути (наприклад, git push origin +masterщоб натиснути на masterгілку).


30
ви також можетеgit push --force origin master
Daenyth

7
Daenyth : Так, але я завжди віддаю перевагу цьому синтаксису, оскільки цей коротший.
Алан Хаггай Алаві

85
І звичайно, розумійте, що якщо хтось, можливо, витяг із віддаленого сховища, ви, мабуть, цього не хочете робити - відповідь у такому випадку - "ви цього не робите".
Каскабель

10
Крім того, я думаю, що ОП точно копіює команду git rebase -i origin/master, і насправді хоче знати, як перезагрузка здійснює віддалення назад, ніж це, наприклад git rebase -i origin/master~20 master.
Каскабель

6
gstackoverflow :+примушує лише відображення, яке воно префіксом. --forceзмусить усі тиски, що відсуваються. Будь ласка, дивіться оновлену відповідь.
Алан Хаггай Алаві

119

На гілці я зміг це зробити так (за останні 4 коміти)

git checkout my_branch
git reset --soft HEAD~4
git commit
git push --force origin my_branch

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

3
Тонна? Як це може бути більше 4? Чи можете ви докладно?
jakob-r

У цьому я не впевнений, але це мало щось спільне зі спробою розігнати і без того поштовх. Дивиться , як інші відчули подібне тут - stackoverflow.com/questions/5189560 / ...
cchamberlain

4
Я прийняв би це як очікувану відповідь. Більш чистий, що прийняв відповідь.
vikramvi

4
Це найбільш зрозуміла і прийнята відповідь всього за 4 кроки
Амея Салагре

45

Незначна різниця у прийнятій відповіді, але у мене виникли великі труднощі з прищепленням, і нарешті я його отримав.

$ git rebase -i HEAD~4
  • На інтерактивному екрані, який відкриється, замініть вибір на сквош вгорі на всі зобов'язання, які ви хочете зробити кабачковими.
  • Збережіть і закрийте редактор наскрізь esc --> :wq

Перейдіть до пульта, використовуючи:

$ git push origin branch-name --force

2
стислий та ефективний, досконалий:
terwxqian

22

Багато проблем можна уникнути, лише створивши branchроботу над & не працюючи над master:

git checkout -b mybranch

Наступні роботи для remoteкомітетів, які вже натиснуті, і суміш remoteвисунутих комітетів / localлише зобов'язань:

# example merging 4 commits

git checkout mybranch
git rebase -i mybranch~4 mybranch

# at the interactive screen
# choose fixup for commit: 2 / 3 / 4

git push -u origin +mybranch

У мене також є кілька записок про запит, які можуть бути корисними.


17

git rebase -i master

ви відкриєте редактор vm відкритим і будете повідомляти щось подібне

Pick 2994283490 commit msg1
f 7994283490 commit msg2
f 4654283490 commit msg3
f 5694283490 commit msg4
#Some message 
#
#some more

Тут я змінив вибір для всіх інших комісій на "f" (Стенди для виправлення).

git push -f origin feature/feature-branch-name-xyz

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


3

Працюючи з Gitlab або Github, ви можете зіткнутися з неприємностями таким чином. Ви пригнічуєте свої зобов’язання одним із наведених вище способів. Моя улюблена одна:

git rebase -i HEAD~4
or
git rebase -i origin/master

виберіть сквош або фіксацію для вашого вчинку. У цей момент ви б перевірили стан git. І повідомлення може бути:

    On branch ABC-1916-remote
    Your branch and 'origin/ABC-1916' have diverged,
    and have 1 and 7 different commits each, respectively.
      (use "git pull" to merge the remote branch into yours)

І ти можеш спокуситися витягнути його. НЕ РОБИТИ ЦЕ, або ви опинитесь у тій же ситуації, що і раніше.

Замість цього натисніть на своє походження за допомогою:

git push origin +ABC-1916-remote:ABC-1916

+ Дозволяють примушувати натискати лише на одну гілку.


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

2

Для збивання двох комітів, один з яких уже був висунутий, на одній гілці працювали наступні:

git rebase -i HEAD~2
    [ pick     older-commit  ]
    [ squash   newest-commit ]
git push --force

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


2

1) git rebase -i HEAD~4

Докладно: Це працює на поточній галузі; HEAD ~ 4 означає розрізання останніх чотирьох комітів; інтерактивний режим (-i)

2) У цей момент редактор відкрив, зі списком комітетів, змінити другий і наступний коміти, замінивши вибір на сквош, а потім збережіть його.

висновок: Успішно перезавантажено та оновлено refs / heads / name-branch

3) git push origin refs/heads/branch-name --force

вихід:

remote:
remote: To create a merge request for branch-name, visit:
remote: http://xxx/sc/server/merge_requests/new?merge_request%5Bsource_branch%5D=sss
remote:To ip:sc/server.git
 + 84b4b60...5045693 branch-name -> branch-name (forced update)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.