Git: Як розчавити всі комірки на гілці


315

Я роблю нову гілку masterз:

git checkout -b testbranch

Я роблю в неї 20 комітів.

Тепер я хочу скинути ці 20 комітів. Я роблю це з:

git rebase -i HEAD~20

Що робити, якщо я не знаю, скільки комітетів? Чи є спосіб зробити щось на кшталт:

git rebase -i all on this branch

6
Ви можете зробити, git rebase -i 58333012713fc168bd70ad00d191b3bdc601fa2dщо зробить інтерактивну базу даних, де номер комітету є останньою коміткою, яка залишається незмінною
— ден

@denns Використовуючи цей метод з останньою комісією у галузі, ви відмовляєтеся від фантастичної роботи. Дуже дякую!
— Джошуа Пінтер

Відповіді:


393

Ще один спосіб зменшити всі ваші зобов’язання - це скинути індекс до головного:

 git checkout yourBranch
 git reset $(git merge-base master yourBranch)
 git add -A
 git commit -m "one commit on yourBranch"

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


EDIT: вам потрібно буде скористатися git push --force


Карлоча Хоа додає в коментарях :

Для скидання можна зробити

git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD)) 

[Що] автоматично використовує гілку, на якій ви зараз перебуваєте.
І якщо ви використовуєте це, ви також можете використовувати псевдонім, оскільки команда не покладається на ім'я гілки .


2
Краще оформити замовлення, щоб здійснити місце, де YourBranchзараз є. Це залишиться YourBranchнедоторканим, коли ви це зробитеreset
— Євген Конков

1
@ Abdurrahim Або відкрийте git bash, і ви можете скопіювати та вставити команди команди!
— VonC

3
Для скидання можна зробити git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))автоматичне використання гілки, на якій ви зараз перебуваєте. І якщо ви використовуєте це, ви також можете використовувати псевдонім, оскільки команда не покладається на ім'я гілки.
— Карлочча Хоа

1
@Druska Для спрощених випадків розгалуження, ні, це повинно працювати добре.
— VonC

1
@Shimmy так, якщо ви змусили натиснути після скидання: git push --force(і попередити своїх колег, якщо у вас є кілька людей, які працюють на цій гілці)
— VonC,

112

Оформіть відділення, для якого ви хочете зібрати всі зобов’язання за один комітет. Припустимо , його називають, feature_branch.

git checkout feature_branch

Крок 1:

Зробіть м'який перезавантаження origin/feature_branchвашої локальної masterфілії (залежно від ваших потреб, ви також можете скинути з походженням / головним). Це скине всі зайві зобов’язання у вашому feature_branch, але не змінюючи жодних змін вашого файлу локально.

git reset --soft master

Крок 2:

Додайте всі зміни у свій каталог git repo до нового комітету, який буде створено. І виконайте те ж саме з повідомленням.

git add -A && git commit -m "commit message goes here"


6
Це було найнадійнішим рішенням для мене - не викликати жодних помилок перезавантаження та конфліктів злиття.
— ANTARA

1
Попередження: додавання git -Додати все, що є у локальній папці - до гілки.
— Девід Н

люблю це рішення! це саме те, що я хотів!
— jacoballenwood

1
Найкраще рішення для noob - не руйнівний і єдиний момент ой, можливо, перевірка занадто багато таких, як секрети додатків тощо, що не має значення, якщо у вас є належний файл
— gitignore

@NSduToit Коротка відповідь: Ні, не потрібно. Зробивши вищезазначені кроки у моїй відповіді, ви закінчитеся одним фіксом із деякими змінами коду. Ви можете думати про це так само, як і про будь-який інший документ із деякими змінами коду. Ви можете натиснути це на вашу віддалену гілку без -fпрапора.
— примхливий

110

Те, що ви робите, є досить схильним до помилок. Просто зробіть:

git rebase -i master

яка автоматично перезавантажує лише зобов'язання вашої філії на поточного останнього головного майстра.


5
дякую, я це зрозумів, але чому схильна моя системна помилка
— user3803850

10
Можливо, тому, що легко зрозуміти число неправильно?
— Даніель Скотт

13
Погодився, це найкраще рішення. але перейдіть за цим посиланням, оскільки це краще пояснює, що вам потрібно зробити.
— Крісто

3
Замість того, щоб розкручувати коміти, ви можете об'єднати гілку до master та зробити git reset to origin / master для нестабільності всіх комітів. Це дозволить вам скористатись наявним нестандартним кодом зcommit -am "the whole thing!"
— nurettin

2
@nurettin Я думаю, що reset origin/masterметод дійсно поганий, оскільки це точно так само, як робити зобов’язання безпосередньо на master - немає історії "об'єднання гілки", немає можливості запиту на тягу. Відповідь @WaZaA набагато більше відповідає нормальному робочому процесу Git, я думаю
— Drenai

79

Ще один простий спосіб зробити це: перейти на гілку походження та зробити а merge --squash. Ця команда не виконує "розбитого" скоєння. коли ви це зробите, всі повідомлення про ваш пристрій будуть зібрані.

$ git checkout master
$ git merge --squash yourBranch
$ git commit # all commit messages of yourBranch in one, really useful
 > [status 5007e77] Squashed commit of the following: ...

1
Правда. Я згадав різницю між злиттям --squash і Rebase -i в stackoverflow.com/a/2427520/6309
— VonC

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

Привіт товариш, чудова порада!
— Нестор

приємно! я створюю "temp" гілку від "master" спочатку для того, щоб розбити "yourBranch", а потім об'єднати "temp" у "master".
— lazieburd

34

Якщо припустити, що ви відгалужуєтесь від головного, вам не потрібно yourBranchвесь час вступати в крок скидання:

git checkout yourBranch
git reset --soft HEAD~$(git rev-list --count HEAD ^master)
git add -A
git commit -m "one commit on yourBranch"

Пояснення :

  • git rev-list --count HEAD ^masterрахує комісії, коли ви створили свою галузь функції у майстра, f.ex. 20.
  • git reset --soft HEAD~20здійснить плавне скидання останніх 20 комісій. Це залишає ваші зміни у файлах, але видаляє коміти.

Використання :

У свій .bash_profile я додав псевдонім для gisquashцього за допомогою однієї команди:

# squash all commits into one
alias gisquash='git reset --soft HEAD~$(git rev-list --count HEAD ^master)'

Після перезавантаження та вчинення вам потрібно зробити git push --force.

Підказка :

Якщо ви використовуєте Gitlab> = 11.0, вам більше цього не потрібно робити, оскільки у нього є опція розсікання при об’єднанні гілок. Варіант сквашування Gitlab


15

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

git reset --soft $(git merge-base master YOUR_BRANCH) && git commit -am "YOUR COMMIT MESSAGE" && git rebase -i master

Це якщо припустити, що майстер є базовою галуззю.


1
Велике спасибі, компанія має чимало обмежень і не змогла перезавантажити звичайний спосіб з редактором, оскільки не була вголос зберегти. Також не вдалося використовувати функцію сквош і злиття в git, оскільки ця гілка переходить до Lead dev для злиття, і йому це не подобається. Цей 1 лайнер спрацював і врятував головний біль. Дивовижна робота.
— L1ghtk3ira

10

Рішення для людей, які віддають перевагу натисканню:

  1. Встановіть sourcetree (безкоштовно)

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

  3. Клацніть правою кнопкою миші на батьківській фіксації. У нашому випадку це головна галузь.

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

  1. Ви можете скосити фіксацію з попередньою, натиснувши кнопку. У нашому випадку ми повинні натиснути 2 рази. Ви також можете змінити повідомлення про фіксацію введіть тут опис зображення

  2. Результати є приголомшливими, і ми готові наполягати! введіть тут опис зображення

Бічна примітка: Якщо ви просували свої часткові зобов’язання на віддалене місце, вам доведеться використовувати силовий натиск після сквошу


Дякую за це!
— Кришталь

0

Іншим рішенням буде збереження всіх журналів фіксування у файл

git log> branch.log

Тепер у branch.log будуть встановлені всі ідентифікатори фіксації з початку.

git reset --soft

всі коміти будуть зняті


0

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

(про галузь розвитку)

git fetch
git merge origin/master  #so development branch has all current changes from master
git reset origin/master  #will show all changes from development branch to master as unstaged
git gui # do a final review, stage all changes you really want
git commit # all changes in a single commit
git branch -f master #update local master branch
git push origin master #push it

0

Весь цей скит скидання, жорсткий, м'який, і все інше, що згадується тут, ймовірно, працює (це не було для мене), якщо ви робите кроки правильно і якийсь джин.
Якщо ви середній Джо Смо, спробуйте це:
Як використовувати git merge - сквош?


Врятувало моє життя і буде моїм піти на сквош, використовуючи це 4 рази, відколи я дізнався про це. Простий, чистий і в основному 1 команда.


Якщо коротко: якщо ви знаходитесь у відділенні, ви можете назвати його "my_new_feature", а ваш запит на витяг має 35 комітів (або скільки завгодно), і ви хочете, щоб це було 1.

А. Переконайтеся, що ваша філія актуальна, продовжуйте роботу розробляти, отримувати останню інформацію та об'єднувати та вирішувати будь-які конфлікти з "my_new_feature"
(цей крок дійсно слід зробити, як тільки можна весь час все-таки)

B. Отримати останню розробку та розгалужити нову гілку, називайте її "my_new_feature_squashed"

C. магія тут.
Ви хочете перенести свою роботу з "my_new_feature" на "my_new_feature_squashed"
Так що просто зробіть (поки на вашій новій гілці ми створили розробку):
git merge --squash my_new_feature

Усі ваші зміни тепер будуть у вашій новій гілці, не соромтесь перевірити її, тоді просто зробіть свою 1 єдину фіксацію, натисніть, новий піар цієї гілки - і чекайте повтору наступного дня.
Ви не любите кодування? :)


0

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

https://github.com/sheerun/git-squash

В основному вам потрібно зателефонувати, git squash masterі ви закінчили

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