Питання Сквош мій останній X доручає разом, використовуючи Git


Як я можу розібрати мій останній X, що з'єднується разом, в одну програму, використовуючи Git?


2322
2018-03-04 04:11


походження


Подібне питання: stackoverflow.com/questions/7275508/... - koppor
Пов'язані: Gіt - комбінація декількох команд, перш ніж штовхати.
@matt TortoiseGit - це ваш інструмент. Вона забезпечує одну функцію "Об'єднати до однієї фіксації", яка автоматично викликає всі кроки у фоновому режимі. На жаль, доступно лише для Windows. Подивіться на мою відповідь нижче. - Matthias M
@Томас: будь ласка, поясніть, як "правильно використовувати" гіт ", коли потрібно виконати відгуки щодо виконуваного коду, і нам потрібно оновити на основі коментарів для перегляду та здійснити повторне виконання, але не хочете натискати канал на основі огляд? - Jeff Learman
Для того, щоб розбитись до першого, здійсніть це - stackoverflow.com/questions/1657017/... - goelakash


Відповіді:


Використовуйте git rebase -i <after-this-commit> і замінити "pick" на другий, а потім здійснювати "squash" або "fixup", як описано в посібник.

У цьому прикладі <after-this-commit> є або хеш SHA1, або відносне місце розташування від HEAD поточної гілки, від якого здійснюються аналізи для команди rebase. Наприклад, якщо користувач хоче переглянути 5 команд із поточної HEAD в минулому, це команда git rebase -i HEAD~5.


1268
2018-03-04 04:18



Це, я думаю, відповідає на це питання трохи краще stackoverflow.com/a/5201642/295797 - Roy Truelove
Що має на увазі під <after-this-commit>? - jtheletter
<after-this-commit> є комбінацією X + 1, тобто батьківкою найстарішої кореспонденції, яку ви хочете скинути. - joozek
Я знайшов цю відповідь занадто короткий, щоб зрозуміти недвозначно. Наприклад, це допомогло б. - Ian Ollmann
Різниця між цим rebase -i підхід і reset --soft є rebase -iдозволяє мені зберігати коректний автор, в той час як reset --soft дозволяє мені перевстановити. Іноді мені потрібно скрушити зобов'язання тягнути запити, але зберігаючи інформацію про автора. Іноді мені потрібно скинути налаштування м'яких на власні команди. Обидві підходи до великих відповідей у ​​будь-якому випадку. - zionyx


Ви можете зробити це досить легко без цього git rebase або git merge --squash. У цьому прикладі ми будемо вибивати останні 3 коми.

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

git reset --soft HEAD~3 &&
git commit

Якщо ви хочете почати редагування нового повідомлення про фінансування з об'єднанням існуючих повідомлень про примусове виконання (наприклад, подібно до того, що вибирати / сквош / сквош / ... / сквош git rebase -i список інструкцій почнеться з вас), то вам потрібно буде витягнути ці повідомлення і передавати їх git commit:

git reset --soft HEAD~3 && 
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"

Обидва ці способи виводять останні три в один і той самий спосіб. Тонкий скидання просто пересуває HEAD до останнього фіксації, який ви не хочете висувати. Ніякий індекс, ані робоче дерево не торкається м'яким скиданням, залишаючи індекс у потрібному стані для вашої нової передачі (тобто він вже має всі зміни, від тих, що збираються "викинути").


2603
2018-03-05 04:19



Ха! Мені подобається цей метод. Саме це замикається на дух проблеми. Шкода, що він вимагає стільки вуду. Щось на зразок цього слід додати до однієї з основних команд. Можливо git rebase --squash-recent, або навіть git commit --amend-many. - Adrian Ratnapala
@ A-B-B: якщо ваша гілка має набір "upstream", то ви можете використовувати його branch@{upstream} (або просто @{upstream} для поточної галузі; в обох випадках остання частина може бути скорочена до @{u}; побачити gitrevisions) Це може відрізнятися від твій "Останній натиснутий фікс" (наприклад, якщо хтось інший натискає те, що збудувався на самому останньому поштовху, а потім ви його завантажили), але, здається, він може бути близьким до потрібного. - Chris Johnsen
Цей тип-сорт вимагав мене push -f але інакше це було чудово, дякую. - 2rs2ts
@ 2rs2ts git push -f звук небезпечний. Будьте обережні, щоб тільки сквошувати місцеві повноваження. Ніколи не торкайтеся штовхнутих команд! - Matthias M
Дякуємо за надання рішення, яке не вимагає вручну набирати сквош / виправлення для кожної окремої фішки, на відміну від всіх інтерактивних пропозицій щодо перебудови в інших місцях. - Antimony


Ви можете використовувати git merge --squash для цього, що трохи витончено, ніж git rebase -i. Припустімо, що ви на майстерні, і ви хочете, щоб кошеняти останні 12 здійснює в один.

ПОПЕРЕДЖЕННЯ: спочатку переконайтеся, що ви виконали свою роботу, перевірте це git status чистий (з git reset --hard викине поетапні та непотрібні зміни)

Потім:

# Reset the current branch to the commit just before the last 12:
git reset --hard HEAD~12

# HEAD@{1} is where the branch was just before the previous command.
# This command sets the state of the index to be as it would just
# after a merge from that commit:
git merge --squash HEAD@{1}

# Commit those squashed changes.  The commit message will be helpfully
# prepopulated with the commit messages of all the squashed commits:
git commit

The документація для git merge описує --squash варіант більш детально.


Оновлення: Єдина реальна перевага цього методу над простішою git reset --soft HEAD~12 && git commit запропонований Крісом Джонсеном в Росії його відповідь це те, що ви отримуєте коректне повідомлення, попередньо заповнене кожним повідомленням про порушення, яке ви стискаєте.


575
2018-03-04 06:10



Ви кажете, що це більш "елегантно", ніж git rebase -i, але ви не даєте причину чому. Орієнтовно 1-е це, тому що мені здається, що насправді навпаки, це правда, і це руйнування; Ви не виконуєте більше команд, ніж потрібно, щоб просто змусити git merge робити одну з речей, що git rebase спеціально призначений для? - Mark Amery
@ Марк Емірі: Є різні причини, за якими я сказав, що це більш елегантно. Наприклад, це не потребує необгрунтованого створення редактора, а потім пошуку та заміни рядка у файлі "to-do". Використовуючи git merge --squash також простіше використовувати в скрипті. По суті, аргументовано те, що вам не потрібна "інтерактивність" git rebase -i зовсім для цього. - Mark Longair
Ще однією перевагою є те, що git merge --squash менш імовірно, що створюватимуть конфлікти злиття перед лицем переміщення / видалення / перейменування порівняно з переробкою, особливо якщо ви з'єднуєтесь із місцевою гілкою. (відмова від відповідальності: виходячи лише з одного досвіду, виправте мене, якщо в загальному випадку це не відповідає дійсності!) - Cheezmeister
Я завжди дуже не хочу, коли справа доходить до жорстких скидів - замість того, щоб я використовував тимчасовий тег HEAD@{1} просто бути на безпечній стороні, наприклад коли робочий процес переривається на годину через відключення живлення тощо. - Tobias Kienzler
@B T: знищила вашу фіксацію? ((Я не знаю, що ви маєте на увазі під цим.Що щось, що ви зробили, ви легко зможете повернутись з reflog git.Якщо у вас була незадіяна робота, але файли були встановлені, ви все одно зможете отримати їх вміст назад хоча це буде більше роботи. Однак якщо ваша робота навіть не була влаштована, я боюся, що цього не станеться; саме тому відповідь каже: "Спочатку перевірте, чи статус git є чистим (оскільки скидання git - сміття буде викидати поетапні та нестабілізовані зміни)". - Mark Longair


Я рекомендую уникати git reset коли це можливо - особливо для Git-novice. Якщо вам не потрібно автоматизувати процес на основі а номер з коментарів, існує менш екзотичний спосіб ...

  1. Покладіть, що підлягають розбиттю, здійснює робочі гілки (якщо вони ще не є) - використовуйте gitk для цього
  2. Перевірте цільову гілку (наприклад, "майстер")
  3. git merge --squash (working branch name)
  4. git commit

Повідомлення про скоєння буде попередньо завантажено на основі сквошу.


136
2018-03-14 23:24



Це найбезпечніший спосіб: без скидання програмного / жорсткого (!!), або використання reflog! - TeChn4K
Було б чудово, якщо б ви розширили (1). - Adam
@ Адам: в принципі, це означає, що використовується графічний інтерфейс користувача gitk щоб позначити рядок коду, який ви стискаєте, а також накреслити основу, на якій можна шкутувати. У звичайному випадку обидві ці ярлики вже існують, тому крок (1) може бути пропущений. - nobar
Зауважте, що цей метод не позначає робочу гілку як повністю об'єднану, тому видалення вимагає примусового видалення. :( - Kyrstellaine
Для (1), я знайшов git branch your-feature && git reset --hard HEAD~N найзручніший спосіб. Проте, воно включає повторне скидання git, яке ця спроба намагалася уникнути. - eis


На підставі Відповідь Кріса Джонсена,

Додайте глобальний псевдонім "squash" від bash: (або Git Bash у Windows).

git config --global alias.squash '!f(){ git reset --soft HEAD~${1} && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"; };f'

... або за допомогою командного рядка Windows:

git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"


Твій ~/.gitconfig тепер має містити це псевдонім:

[alias]
    squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"


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

git squash N

... Котрий автоматично шматує разом останнє N зобов'язує, включно.

Примітка: результуюче повідомлення про виконання - це комбінація всіх ускладнених команд у порядку. Якщо ви незадоволені цим, ви завжди можете git commit --amendзмінити його вручну. (Або змініть псевдонім відповідно до ваших уподобань.)


97
2018-02-19 19:21



Цікаво, але я б напевно набрав повідомлення squashed commit, як описовий підсумок моїх кількох помилок, ніж це було автоматично введено для мене. Тож я краще вказати git squash -m "New summary." і є N визначається автоматично, як кількість неприкріплених зобов'язань. - A-B-B
@ A-B-B, це звучить як окреме питання. (Я не думаю, що це саме те, про що запитав О.П., я ніколи не відчував потреби в цьому у своєму робочому процесі зі шкільним десктомом). - EthanB
Це дуже мило. Особисто я хотів би, щоб версія, яка використовує повідомлення про фінансування, з першого зі складних зобов'язань. Було б добре для таких речей, як налаштування пробілу. - funroll
@funroll узгодили. Просто скидання останнього поштового повідомлення є надзвичайно необхідним для мене. Ми повинні вміти придумати це ... - Steve Clay
@ A-B-B можна використовувати git commit --amend для подальшого зміни повідомлення, але цей псевдонім дозволяє вам добре розпочати роботу над тим, що повинно бути в повідомленні про порушення. - dashesy


Якщо ви використовуєте TortoiseGit, ви можете виконувати цю функцію Combine to one commit:

  1. Відкрийте контекстне меню TortoiseGit
  2. Виберіть Show Log
  3. Позначте відповідні команди у вікні журналу
  4. Виберіть Combine to one commit з контекстного меню

Combine commits

Ця функція автоматично виконує всі необхідні одиничні дії. На жаль, доступно лише для Windows.


46
2017-11-06 12:51



Наскільки я знаю, це не спрацює для злиття. - Thorkil Holm-Jacobsen
Хоча це не коментує жоден інший, це навіть працює для зобов'язань, які не входять в HEAD. Наприклад, моя потреба полягала в тому, щоб позбутися деяких завдань WIP, які я зробив, з більш розумним описом, перш ніж натискати. Працював красиво. Звичайно, я все ще сподіваюсь, що зможу навчитися робити це за допомогою команд. - Charles Roberto Canato


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

git rebase -i HEAD~3

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

Команда відкриє інтерактивний редактор rebase, який потім дозволить вам перевпорядкувати, сквош, переформатувати і т.д., як за звичайним.


46
2018-05-17 06:19