GIT модифицировать сообщение об истории фиксации с одним сообщением между двумя хэшем commit [duplicate]

Я предлагаю вам добавить

#!/usr/bin/env python

вместо #!/usr/bin/python в верхней части файла. Причина этого в том, что установка python может находиться в разных папках в разных дистрибутивах или на разных компьютерах. Используя env, вы убедитесь, что система находит python и делегирует выполнение сценария.

Как уже говорилось, чтобы сделать исполняемый файл сценария, например:

chmod u+x name_of_script.py

должен делать.

2491
задан Vadim Kotov 8 September 2017 в 09:09
поделиться

29 ответов

Используйте git rebase -i <after-this-commit> и замените «pick» на второй и последующие фиксации «squash» или «fixup», как описано в в руководстве .

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

1274
ответ дан J4cK 15 August 2018 в 19:16
поделиться
  • 1
    Это, я думаю, немного отвечает на этот вопрос stackoverflow.com/a/5201642/295797 – Roy Truelove 1 May 2013 в 15:22
  • 2
    Что подразумевается под <after-this-commit>? – jtheletter 4 November 2014 в 06:49
  • 3
    <after-this-commit> является фиксацией X + 1, то есть родительской старейшей фиксации, которую вы хотите сквош. – joozek 4 November 2014 в 13:04
  • 4
    Я нашел этот ответ слишком кратким, чтобы понять однозначно. Пример мог бы помочь. – Ian Ollmann 4 June 2015 в 17:23
  • 5
    Разница между этим подходом rebase -i и reset --soft равна rebase -i, позволяет мне сохранить автора фиксации, а reset --soft позволяет мне повторно подтвердить. Иногда мне нужно выполнять сквош-фиксацию запросов на тягу, сохраняя при этом информацию об авторе. Иногда мне нужно сбросить софт самостоятельно. В любом случае, это оправдывает оба больших ответа. – zionyx 15 September 2015 в 09:31

В ветке вы хотели бы объединить коммиты, запустить:

git rebase -i HEAD~(n number of commits back to review)

. Это откроет текстовый редактор, и вы должны переключить 'pick' перед каждой фиксацией на 'squash' если вы хотите, чтобы эти коммиты были объединены вместе. Например, если вы хотите объединить все коммиты в единицу, «выбрать» - это первая фиксация, которую вы сделали, и все будущие должны быть настроены на «squash». Если вы используете vim, используйте: x в режиме вставки, чтобы сохранить и выйти из редактора.

Затем, чтобы завершить rebase:

git rebase --continue

Подробнее об этом и других способах переписать история фиксации см. этот полезный пост

2
ответ дан aabiro 15 August 2018 в 19:16
поделиться

Просто добавьте эту функцию bash в ваш bash файла .zshrc.

# Squash last X commits with a Commit message.
# Usage: squash X 'COMMIT_MSG'
# where X= Number of last commits.
# where COMMIT_MSG= New commit msg.
function squash() {
    if [ -z "${1}" -o -z "${2}" ]; then
        echo "Usage: \`squash X COMMIT_MSG\`"
        echo "X= Number of last commits."
        echo "COMMIT_MSG= New commit msg."
        return 1
    fi

    git reset --soft HEAD~"$1"
    git add . && git ci -m "$2" # With 100 emoji
    git push --force
}

Затем просто запустите

squash X 'New Commit Message'

И все готово.

-1
ответ дан Ahmad Awais 15 August 2018 в 19:16
поделиться
  • 1
    Не знаю, почему люди запустили рабочее решение без комментариев. – Ahmad Awais 12 February 2018 в 14:29

Как насчет ответа на вопрос, связанный с таким рабочим процессом?

  1. много локальных коммитов, , смешанных с несколькими слияниями FROM master ,
  2. , наконец, нажать на удаленный,
  3. PR и слить TO master рецензентом . (Да, разработчику было бы легче merge --squash после PR, но команда подумала, что это замедлит процесс.)

Я не видел такой рабочий процесс на этой странице. (Возможно, это мои глаза.) Если я правильно понял rebase, для нескольких объединений потребуется несколько разрешений конфликтов. Я не хочу даже думать об этом!

Итак, это, похоже, сработает для нас.

  1. git pull master
  2. git checkout -b new-branch
  3. git checkout -b new-branch-temp
  4. редактировать и фиксировать много локально, регулярно выполнять слияние
  5. git checkout new-branch
  6. git merge --squash new-branch-temp // помещает все изменения в стадии
  7. git commit 'one message to rule them all'
  8. git push
  9. Рецензент делает PR и сливается с мастером.
0
ответ дан allenjom 15 August 2018 в 19:16
поделиться

Что может быть действительно удобно: найдите хеш-фиксацию, которую вы хотите сквозировать поверх; скажем, что это d43e15 Теперь используйте

git reset d43e15

git commit -am 'new commit name'

7
ответ дан Ariel Gabizon 15 August 2018 в 19:16
поделиться

Благодаря этому удобному сообщению в блоге я обнаружил, что вы можете использовать эту команду для раздачи последних трех коммитов:

git rebase -i HEAD~3

Это удобно, поскольку это работает, даже если вы находятся в локальном филиале без информации отслеживания / удаленного репо.

Команда откроет интерактивный редактор переадресации, который затем позволит вам изменить порядок, сквош, переименование и т. д. как обычно.

48
ответ дан br3nt 15 August 2018 в 19:16
поделиться

Это супер-пупер kludgy, но каким-то классным способом, поэтому я просто брошу его в кольцо:

GIT_EDITOR='f() { if [ "$(basename $1)" = "git-rebase-todo" ]; then sed -i "2,\$s/pick/squash/" $1; else vim $1; fi }; f' git rebase -i foo~5 foo

Перевод: предоставить новый «редактор» для git, который , если редактируемое имя файла git-rebase-todo (приглашение интерактивной переадресации) изменяет все, кроме первого «выбрать» на «сквош», а в противном случае порождает vim, так что когда вам будет предложено отредактировать сжатое сообщение фиксации, вы получить vim. (И, очевидно, я раздавил последние пять коммитов на ветке foo, но вы можете изменить это, как вам нравится.)

Я, вероятно, сделаю то, что предложил Марк Лонгэй .

97
ответ дан Community 15 August 2018 в 19:16
поделиться
  • 1
    +1: это весело и поучительно, потому что для меня совершенно не очевидно, что вы можете поставить что-нибудь более сложное, чем имя программы в переменной среды GIT_EDITOR. – Mark Longair 4 March 2011 в 22:04
  • 2
    Интересно, но я бы скорее напечатал сообщение squashed commit, как описательное резюме моих нескольких коммитов, чем его авто-ввод для меня. Поэтому я бы предпочел указать git squash -m "New summary." и автоматически определить N как число нечистых коммитов. – A-B-B 22 April 2014 в 19:50
  • 3
    @ A-B-B, Это звучит как отдельный вопрос. (Я не думаю, что это именно то, о чем спрашивал OP, я никогда не чувствовал необходимости в этом в рабочем процессе git squash). – EthanB 23 April 2014 в 23:29
  • 4
    Это довольно мило. Лично мне нужна версия, которая использует сообщение фиксации от первой из раздавленных коммитов. Было бы хорошо для таких вещей, как простейшие твики. – funroll 10 July 2014 в 02:40
  • 5
    @funroll Согласен. Просто отбросить последнее сообщение об ошибке - это большая общая потребность для меня. Мы должны уметь это ... – Steve Clay 26 September 2014 в 16:52
  • 6
    @ A-B-B вы можете использовать git commit --amend для дальнейшего изменения сообщения, но этот псевдоним позволяет вам хорошо начать то, что должно быть в сообщении фиксации. – dashesy 14 July 2016 в 15:59

Вы можете использовать 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

Документация для git merge более подробно описывает параметр --squash.


Обновление: единственное реальное преимущество этого метода по сравнению с более простым git reset --soft HEAD~12 && git commit, предложенным Крисом Джонсеном в , его ответом является то, что вы получаете сообщение о фиксации preopulated с каждым сообщением фиксации, которое вы раздавите.

577
ответ дан ErikE 15 August 2018 в 19:16
поделиться
  • 1
    Вы говорите, что это более «элегантно», чем git rebase -i, но вы не даете причины. Ориентировочно это, потому что мне кажется, что на самом деле обратное верно, и это взломать; вы не выполняете больше команд, чем необходимо, только для того, чтобы заставить git merge делать одно из того, что специально предназначено для git rebase? – Mark Amery 8 July 2013 в 12:14
  • 2
    @Mark Amery: Есть разные причины, по которым я сказал, что это более элегантно. Например, он не требует излишнего нереста редактора, а затем выполняет поиск и замену для строки в & quot; to-do & quot; файл. Использование git merge --squash также проще в использовании в скрипте. По существу, рассуждение состояло в том, что вам не нужна «интерактивность». из git rebase -i вообще для этого. – Mark Longair 8 July 2013 в 16:59
  • 3
    Другим преимуществом является то, что git merge --squash с меньшей вероятностью создает конфликты слияния при перемещении / удалении / переименованиях по сравнению с rebasing, особенно если вы сливаетесь из локальной ветви. (отказ от ответственности: основываясь только на одном опыте, исправьте меня, если это не так в общем случае!) – Cheezmeister 28 February 2014 в 00:21
  • 4
    Я всегда очень неохотно отношусь к жестким сбрасываниям - я бы использовал временный тег вместо HEAD@{1}, чтобы быть в безопасности, например. когда ваш рабочий процесс прерывается в течение часа при отключении питания и т. д. – Tobias Kienzler 11 August 2014 в 13:18
  • 5
    @B T: Разрушил вашу фиксацию? :( Я не уверен, что вы подразумеваете под этим. Все, что вы совершили, вы легко сможете получить обратно из reflog git. Если у вас была незавершенная работа, но файлы были поставлены, вы все равно сможете получить их содержание назад, , хотя это будет больше работы . Однако, если ваша работа даже не была поставлена, я боюсь, что это мало что можно сделать, поэтому ответ говорит о начале: & quot; ; Сначала проверьте, что статус git чист (поскольку git reset - hard выкинет поэтапные и неустановленные изменения). – Mark Longair 22 May 2016 в 09:55

Я нахожу, что более общим решением является не указание «N» коммитов, а скорее идентификатор ветки / фиксации, который вы хотите раздавить поверх. Это менее подвержено ошибкам, чем подсчет коммиттов до определенного коммита - просто укажите тег напрямую или если вы действительно хотите подсчитать, вы можете указать HEAD ~ N.

В моем рабочем процессе я запускаю ветви, и моя первая фиксация на этой ветке суммирует цель (т.е. обычно это то, что я буду нажимать как «окончательное» сообщение для этой функции в публичный репозиторий.) Поэтому, когда я закончил, все, что я хочу сделать, это git squash master назад к первому сообщению, а затем я готов нажать.

Я использую псевдоним:

squash = !EDITOR="\"_() { sed -n 's/^pick //p' \"\\$1\"; sed -i .tmp '2,\\$s/^pick/f/' \"\\$1\"; }; _\"" git rebase -i

Это сбрасывает историю, раздавленную до того, как она это сделает - это дает вам возможность восстановиться, захватив старый идентификатор фиксации с консоли, если вы хотите вернуться. (Пользователи Solaris отмечают, что используют параметр GNU sed -i, пользователи Mac и Linux должны быть в порядке с этим.)

3
ответ дан Ethan 15 August 2018 в 19:16
поделиться
  • 1
    Я попробовал псевдоним, но я не уверен, что заменители sed имеют какой-либо эффект. Что они должны делать? – raine 21 March 2015 в 19:04
  • 2
    Первый sed просто сбрасывает историю на консоль. Второй sed заменяет все «pick» на «f» (fixup) и перезаписывает файл редактора на месте (опция -i). Итак, вторая делает всю работу. – Ethan 22 April 2015 в 20:28
  • 3
    Вы правы, считая N-число конкретных коммитов, очень подверженных ошибкам. Он несколько раз ввернул меня и потратил впустую, пытаясь отменить rebase. – Igor Ganapolsky 2 October 2015 в 00:37
  • 4
    Привет, Итан, я хотел бы знать, скроет ли этот рабочий процесс возможные конфликты при слиянии. Поэтому, пожалуйста, подумайте, есть ли у вас два ведомых мастера и подчиненные. Если подчиненный конфликт имеет конфликт с ведущим, и мы используем git squash master, когда мы проверяем ведомое устройство. что это будет? скроем конфликт? – Sergio Bilello 24 February 2016 в 08:55
  • 5
    @Sergio Это случай переписывания истории, поэтому у вас, вероятно, будут конфликты, если вы выполните сквош-фиксации, которые уже были нажаты, а затем попытайтесь объединить / переустановить сжатую версию. (Некоторые тривиальные случаи могут сойти с рук.) – Ethan 28 June 2016 в 01:51

В дополнение к другим отличным ответам я хотел бы добавить, как git rebase -i всегда путает меня с порядком фиксации - от старого до более нового или наоборот? Итак, это мой рабочий процесс:

  1. git rebase -i HEAD~[N], где N - число коммитов, которые я хочу присоединиться, , начиная с самого последнего . Таким образом, git rebase -i HEAD~5 будет означать «squash последние 5 коммитов в новый»;
  2. редактор появляется, показывая список коммитов, которые я хочу объединить. Теперь они отображаются в в обратном порядке : старший фиксатор находится сверху. Отметьте как «squash» или «s» все коммиты там , кроме первого / более старого : он будет использоваться в качестве отправной точки. Сохраните и закройте редактор;
  3. редактор снова появится с сообщением по умолчанию для нового коммита: измените его на свои нужды, сохраните и закройте. Сквош завершен!

Источники и amp; дополнительные сообщения: # 1 , # 2 .

2
ответ дан Ignorant 15 August 2018 в 19:16
поделиться

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

Если вы хотите записать новое сообщение о фиксации с нуля, это достаточно:

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

Если вы хотите начать редактируя новое сообщение фиксации с помощью конкатенации существующих сообщений фиксации (т. е. похоже на то, что будет запускать список инструкций pick / squash / squash / ... / squash git rebase -i), тогда вам нужно извлечь эти сообщения и передать их git commit:

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

Оба этих метода скворуют последние три коммита в один новый коммит таким же образом. Мягкий сброс просто перенаправляет HEAD на последнюю фиксацию, которую вы не хотите раздавить. Ни индекс, ни рабочее дерево не касаются мягкого сброса, оставляя индекс в желаемом состоянии для вашего нового коммита (т. Е. Он уже имеет все изменения от коммитов, которые вы собираетесь «выбросить»).

2610
ответ дан iwasrobbed 15 August 2018 в 19:16
поделиться
  • 1
    Ха! Мне нравится этот метод. Это тот, кто близок к духу проблемы. Жаль, что для этого требуется столько вуду. Что-то вроде этого должно быть добавлено к одной из основных команд. Возможно git rebase --squash-recent или даже git commit --amend-many. – Adrian Ratnapala 8 November 2013 в 19:50
  • 2
    @ABB: Если ваша ветка имеет «восходящий» набор, тогда вы можете использовать branch@{upstream} (или только @{upstream} для текущей ветви; в обоих случаях последняя часть может быть сокращена до @{u}; [д0] gitrevisions [/ д0]). Это может отличаться от вашего "последнего нажатого фиксации" (например, если кто-то другой нажал что-то, что было создано на вашем последнем нажатии, а затем вы его выбрали), но похоже, что он может быть близок к тому, что вы хотите. – Chris Johnsen 23 April 2014 в 07:13
  • 3
    Этот вид-сортировка потребовал от меня push -f, но в остальном это было прекрасно, спасибо. – 2rs2ts 30 October 2014 в 00:32
  • 4
    @ 2rs2ts git push -f звучит опасно. Позаботьтесь только о склеивании локальных коммитов. Никогда не прикасайтесь к толчкам! – Matthias M 24 September 2015 в 14:49
  • 5
    – Zach Saucier 21 July 2016 в 00:21
  • 6
    Благодарим вас за предоставление решения, которое не требует ручного ввода squash / fixup для каждой отдельной фиксации, в отличие от всех предложений по интерактивной переадресации в других местах. – Antimony 10 April 2017 в 16:32

Для этого вы можете использовать следующую команду git.

 git rebase -i HEAD~n

n (= 4 здесь) - это номер последней фиксации. Затем вы получите следующие опции:

pick 01d1124 Message....
pick 6340aaa Message....
pick ebfd367 Message....
pick 30e0ccb Message....

Обновить, как показано ниже,

p 01d1124 Message....
s 6340aaa Message....
s ebfd367 Message....
s 30e0ccb Message....

Подробнее см. Ссылку

Удачи !!

24
ответ дан Jakir Hosen Khan 15 August 2018 в 19:16
поделиться

Другой способ сделать это, если у вас есть тонна коммитов, - сделать сквош ПОСЛЕ фиксации, как git rebase -i <hashbeforeyouwanttosquash>

. Это откроет ваш редактор, чтобы выбрать / сквош, как обычно.

См. https://git-scm.com/docs/git-rebase#_interactive_mode

0
ответ дан Jazzy 15 August 2018 в 19:16
поделиться

Взгляните на этот смысл:

Gist - Easy git-squash

Вам нужно будет ввести, например. git-squash 3 и все. Последние три коммита объединяются в один с конкатенированными сообщениями.

2
ответ дан jotaelesalinas 15 August 2018 в 19:16
поделиться

Переключитесь на главную ветку и убедитесь, что вы в курсе:

sh git checkout master && git fetch && git pull

Объедините ветвь вашей функции в ведущую ветвь локально:

sh git merge feature_branch

Сбросить локальную ведущую ветвь в состояние начала:

sh git reset origin/master

Теперь все ваши изменения считаются неустановленными. Вы можете выполнить и передать их в одну или несколько коммитов.

sh git add . --all git commit

-3
ответ дан Leo Lanese 15 August 2018 в 19:16
поделиться

В вопросе может быть неоднозначным, что подразумевается под «последним».

, например git log --graph выводит следующее (упрощенное):

* commit H0
|
* merge
|\
| * commit B0
| |
| * commit B1
| | 
* | commit H1
| |
* | commit H2
|/
|

. Затем последние фиксируются по времени: H0, merge, B0.

Проблема заключается в том, что H0 содержит H1 и H2 (и, как правило, больше коммитов перед слиянием и после ветвления), а B0 - нет. Таким образом, вам нужно управлять изменениями от H0, merge, H1, H2, B0 по крайней мере.

Можно использовать rebase, но по-другому, а затем в других упомянутых ответах:

rebase -i HEAD~2

Это покажет вам варианты выбора (как упоминалось в других ответах):

pick B1
pick B0
pick H0

Поместите сквош вместо выбора в H0:

pick B1
pick B0
s H0

После сохранения и выключения rebase будет применяться фиксация по очереди после H1. Это означает, что он попросит вас снова разрешить конфликты (где HEAD будет сначала H1, а затем накапливает фиксации по мере их применения).

После того, как rebase завершится, вы можете выбрать сообщение для раздавленных H0 и B0:

* commit squashed H0 and B0
|
* commit B1
| 
* commit H1
|
* commit H2
|

PS Если вы просто выполните сброс в BO: (например, используя reset --mixed, который более подробно объясняется здесь https://stackoverflow.com/a/18690845/2405850 ):

git reset --mixed hash_of_commit_B0
git add .
git commit -m 'some commit message'

, тогда вы раздавите в B0 изменения H0, H1, H2 (потеря полностью фиксирует изменения после разветвления и перед слиянием.

3
ответ дан littlewhywhat 15 August 2018 в 19:16
поделиться

Если вы находитесь на удаленной ветке (называемой feature-branch), клонированной из Золотого репозитория (golden_repo_name), то вот техника, чтобы раздавить ваши коммиты в одну:

  1. Оформить заказ золотой репо
    git checkout golden_repo_name
    
  2. Создайте из него новую ветвь (золотой репо) следующим образом
    git checkout -b dev-branch
    
  3. Сквош слияние с вашей локальной ветвью, что вы уже
    git merge --squash feature-branch
    
  4. Зафиксируйте свои изменения (это будет единственный коммит, который идет в dev-ветке)
    git commit -m "My feature complete"
    
  5. Нажмите ветвь в локальный репозиторий
    git push origin dev-branch
    
19
ответ дан Machavity 15 August 2018 в 19:16
поделиться
  • 1
    Поскольку я просто раздавил ~ 100 коммитов (для синхронизации svn-ветвей через git-svn), это намного быстрее, чем интерактивное восстановление! – sage 3 November 2015 в 21:34
  • 2
    Читая, я вижу комментарий @ Chris, что я и делал (rebase -soft ...) - слишком плохо, что stackoverflow больше не ставит ответ сотнями upvotes в верхней части ... – sage 3 November 2015 в 21:35
  • 3
    соглашайтесь с вами @sage, давайте надеяться, что они могут это сделать когда-нибудь в будущем – Sandesh Kumar 3 November 2015 в 21:51

Ответ аномии хорош, но я чувствовал себя неуверенно в этом, поэтому решил добавить пару скриншотов.

Шаг 0: git log

Посмотрите, где вы находитесь git log. Самое главное, найдите хеш фиксации первой фиксации, которую вы не хотите , чтобы сквош. Таким образом, только:

Шаг 1: git rebase

Выполнить git rebase -i [your hash] , в мой случай:

$ git rebase -i 2d23ea524936e612fae1ac63c95b705db44d937d

Шаг 2: выберите / сквош, что вы хотите

В моем случае я хочу раздавить все на коммит, который был первым во времени. Порядок от первого до последнего, так точно так же, как в git log. В моем случае я хочу:

Шаг 3: Отрегулировать сообщения (ы)

Если вы выбрали только одно коммит и раздавили остальное, вы можете настроить одно сообщение фиксации:

Вот и все. Как только вы сохраните это (:wq), все готово. Посмотрите на это с помощью git log.

13
ответ дан Martin Thoma 15 August 2018 в 19:16
поделиться

Если вы используете TortoiseGit, вы можете использовать функцию Combine to one commit:

  1. Открыть контекстное меню TortoiseGit
  2. Выбрать Show Log
  3. Отметить
  4. Эта функция автоматически выполняется все необходимые одиночные шаги git. К сожалению, доступно только для Windows.

46
ответ дан Matthias M 15 August 2018 в 19:16
поделиться
  • 1
    Насколько мне известно, это не будет работать для коммитов. – Thorkil Holm-Jacobsen 26 April 2017 в 09:50
  • 2
    Хотя это не комментируется другими, это даже работает для коммитов, которые не относятся к HEAD. Например, моя потребность заключалась в том, чтобы раздавить некоторые записи WIP, которые я сделал с более разумным описанием перед нажатием. Работала красиво. Конечно, я все еще надеюсь, что смогу научиться делать это по командам. – Charles Roberto Canato 27 April 2018 в 22:03

Я рекомендую избегать git reset, когда это возможно, особенно для Git-новичков. Если вам действительно не нужно автоматизировать процесс, основанный на числе коммитов, существует менее экзотический способ ...

  1. Положите на компромиссные коммиты на (если они еще не установлены) - используйте gitk для этого
  2. Проверьте целевую ветвь (например, «master»)
  3. git merge --squash (working branch name)
  4. git commit

Сообщение фиксации будет предварительно заполнено на основе сквоша.

136
ответ дан nobar 15 August 2018 в 19:16
поделиться
  • 1
    Это самый безопасный метод: без сброса soft / hard (!!) или reflog! – TeChn4K 30 November 2016 в 15:08
  • 2
    Было бы здорово, если бы вы расширили (1). – Adam 11 April 2017 в 14:16
  • 3
    @Adam: В принципе, это означает, что интерфейс GUI gitk должен обозначать строку кода, который вы раздавите, а также наклейте базу, на которую нужно сквозировать. В нормальном случае обе эти метки уже существуют, поэтому шаг (1) можно пропустить. – nobar 11 April 2017 в 21:48
  • 4
    Обратите внимание, что этот метод не указывает, что рабочая ветвь полностью слита, поэтому ее удаление требует принудительного удаления. :( – Kyrstellaine 13 April 2017 в 20:17
  • 5
    Для (1) я нашел git branch your-feature && git reset --hard HEAD~N наиболее удобный способ. Однако он снова включает сброс git, который этот ответ пытался избежать. – eis 30 May 2017 в 17:01

1) Определите короткую хэш-запись фиксации

# git log --pretty=oneline --abbrev-commit
abcd1234 Update to Fix for issue B
cdababcd Fix issue B
deab3412 Fix issue A
....

2) Если вы хотите скворовать (объединить) последние две фиксации

# git rebase -i deab3412 

3) Это открывает кнопку nano для слияния. И это выглядит ниже

....
pick cdababcd Fix issue B
pick abcd1234 Update to Fix for issue B
....

4) Переименуйте слово pick в squash, которое присутствует перед abcd1234. После переименования он должен выглядеть следующим образом.

....
pick cdababcd Fix issue B
squash abcd1234 Update to Fix for issue B
....

5) Теперь сохраните и закройте редактор nano. Нажмите ctrl + o и нажмите Enter для сохранения. И затем нажмите ctrl + x, чтобы выйти из редактора.

6) Затем редактор nano снова открывается для обновления комментариев, при необходимости обновляет его.

7) Теперь его сжатие успешно, вы можете проверить его, проверив журналы.

# git log --pretty=oneline --abbrev-commit
1122abcd Fix issue B
deab3412 Fix issue A
....

8) Теперь нажмите на репо. Примечание, чтобы добавить знак + перед именем ветки.

# git push origin +master

Примечание. Это основано на использовании git на оболочке ubuntu. Если вы используете разные os (Windows или Mac), то выше команды такие же, кроме редактора. Вы можете получить другой редактор.

22
ответ дан rashok 15 August 2018 в 19:16
поделиться
  • 1
    Спасибо за это, лучший путеводитель! – Jeremie Ges 28 March 2018 в 13:49
  • 2
    Он обновляет только последние две коммиты, даже если я сбрасываю идентификатор фиксации на шестой последний фиксатор, не знаю, почему – Carlos Liu 16 July 2018 в 07:06
  • 3

Если вы используете GitUp , выберите фиксацию, которую хотите объединить с ее родителем, и нажмите S. Вы должны сделать это один раз для каждой фиксации, но это намного проще, чем придумать правильное заклинание командной строки. Особенно, если это то, что вы делаете только время от времени.

0
ответ дан SSteve 15 August 2018 в 19:16
поделиться

Основываясь на этой статье , я нашел этот метод более удобным для моей usecase.

. Моя ветка «dev» опередила «origin / dev» на 96 коммитов (так что эти коммиты еще не были отодвинуты на пульт).

Я хотел пробить эти коммиты в один, прежде чем нажимать изменение. Я предпочитаю переустановить ветвь в состояние «origin / dev» (это оставит все изменения с 96 фиксированными неустановленными), а затем зафиксирует изменения сразу:

git reset origin/dev
git add --all
git commit -m 'my commit message'
30
ответ дан trudolf 15 August 2018 в 19:16
поделиться
  • 1
    Только то, что мне было нужно. Squash down фиксируется из моей ветви функции, а затем я беру вишневый выбор, который передается моему хозяину. – David Victor 10 July 2015 в 12:34
  • 2
    Это не сквозит предыдущие коммиты! – Igor Ganapolsky 22 October 2015 в 16:26
  • 3
    не могли бы вы уточнить, что еще немного @igorGanapolsky? – trudolf 3 December 2015 в 06:54
  • 4
    @trudolf На самом деле это не раздавливание (сбор отдельных коммитов для сквоша). Это больше всего, чтобы совершить все ваши изменения сразу. – Igor Ganapolsky 3 December 2015 в 07:26
  • 5
    да, следовательно, он сквозит все ваши коммиты в один. Поздравляем! – trudolf 4 December 2015 в 11:50

Я думаю, что самый простой способ сделать это - сделать новую ветку от мастера и выполнить слияние --squash ветки функции.

git checkout master
git checkout -b feature_branch_squashed
git merge --squash feature_branch

Тогда у вас есть все изменения, готовые для фиксации.

5
ответ дан user1376350 15 August 2018 в 19:16
поделиться
  • 1
    Это довольно легко и просто, отлично! – Carlos Liu 16 July 2018 в 07:06
  • 2
    именно то, что я искал, спасибо человеку! – Aishwat Singh 26 July 2018 в 09:21

Если вы хотите хлюпить каждый совершить в одном коммите (например, при первом выпуске проекта в первый раз), попробуйте:

git checkout --orphan <new-branch>
git commit
10
ответ дан William Denniss 15 August 2018 в 19:16
поделиться
git rebase -i HEAD^^

, где число ^ равно X

(в этом случае сквош две последние коммиты)

3
ответ дан Yoaz Menda 15 August 2018 в 19:16
поделиться
0
ответ дан Alan Dong 5 September 2018 в 18:29
поделиться
1
ответ дан Ayan 5 September 2018 в 18:29
поделиться
98
ответ дан Community 5 September 2018 в 18:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: