git squash и запазете последния комит точно

Получавам конфликти при сливане при смачкване на ангажименти и последният комит завършва РАЗЛИЧЕН, отколкото беше преди скуоша. Защо крайният резултат се променя, когато стартирам

git rebase -i someothercommit

след това скуош нежелани междинни ангажименти, оставяйки само първите?? Не разбирам как може да има конфликти при сливане, като се има предвид, че всеки комит е в серия. Някои повече подробности са по-долу:

За моя работен процес имам няколко клона master 0somefeature 1anotherfeature 2lastfeature

обикновено 0feature се базира на master, 1 се базира на 0 и т.н. когато направя промяна на master, сливам master в 0feature, след това 0feature в 1newfeature и т.н.

това е, което изпълних:

$ git log --online -5
990cfb1 combine dump, add prog, combine validate
41013a9 Merge branch '5flash_addr' into 6flash_bankcheck
6f5e8f1 nothing interesting
7b8140d nothing interesting
2347714 implementation of dump and program

$ git rebase -i 2347714

след това смачквам всички ангажименти с изключение на 990cfb1, завършвам с конфликти при сливане и новият ми комит вече е различен, отколкото беше преди сливането!!

Благодаря!


person swinman    schedule 12.05.2013    source източник


Отговори (2)


Думата „изтриване“ не е правилна във вашето твърдение „тогава изтривам всички ангажименти с изключение на 990cfb1“. Трябва да използвате squash.

Когато стартирате $ git rebase -i 2347714, ще видите изскачащ текстов редактор, показващ всички ваши съобщения по следния начин:

pick 990cfb1 combine dump, add prog, combine validate
pick 41013a9 Merge branch '5flash_addr' into 6flash_bankcheck
pick 6f5e8f1 nothing interesting
pick 7b8140d nothing interesting
pick 2347714 implementation of dump and program

В този момент бих казал НЕ ПИПАЙТЕ първия!(990cfb1). След това, за останалите, заменете "pick" с "squash" или "s" като псевдоним.

Сега запазете файла и излезте от редактора.

След това git rebase ще продължи да работи. След секунди ще се появи друг прозорец на текстов редактор, който ще ви покаже всички съобщения за ангажименти.

В този момент можете спокойно да изтриете всички съобщения и да ги пренапишете в едно изречение като последно съобщение за ангажиране.

Сега, запазете и си тръгнете. Git ще направи следното автоматично. Свършен!

Странична бележка

Може да имате проблем да следвате горния процес, тъй като вашето „rebase“ вече е изпълнено, но спира за някаква грешка.

Ти трябва да:

  1. Първо направете физическо копие на целия git проект някъде другаде!!!
  2. След това стартирайте git rebase --abort
  3. Започнете от чисто състояние, както е описано по-горе.
person Billy Chan    schedule 12.05.2013
comment
всъщност изтривах реда в интерактивния прозорец.. Ако премахнете ред тук, ТОЗИ КОМИТ ЩЕ БЪДЕ ЗАГУБЕН.. - person swinman; 13.05.2013
comment
Благодаря ви за бележката - иска ми се да бях направил това в движение, преди да напиша тази публикация! - person swinman; 13.05.2013
comment
Все още съм любопитен защо получавам толкова много грешки и трябва ръчно да избирам с кой ангажимент да отида? Има ли начин да се каже, винаги избирайте от най-скорошния комит или сливане? Като алтернатива има ли нещо в начина, по който използвам git, което не е правилно? - person swinman; 13.05.2013
comment
изглежда, че вместо да използвам git, би било по-добре да направя нов клон 5somefeature_new от 4other_feature, заменяйки всички файлове с помощта на файловете в 5somefeature, след това изтривайки клона 5somefeature и преименувайки 5somefeature_new обратно на старото име на клон... трябва да бъде по-добър начин за скуош ангажименти!! - person swinman; 13.05.2013
comment
@swinman, работният процес за пребазиране е главно за сливане на клон на функции в главен или друг основен клон за внедряване/разпространение. Когато разработвате функция, трябва да се ангажирате често за малки промени, но за главния, той трябва да е чист. Ето защо тези малки ангажименти в клона на функциите трябва да бъдат комбинирани в едно, преди клонът да бъде обединен за овладяване, като работния процес за пребазиране. - person Billy Chan; 13.05.2013
comment
Как това отговаря на въпроса, просто не отговаря. - person AymenDaoudi; 27.05.2020

Сега станах много по-добър в това... основният проблем беше сливането на "по-стар" клон в новия, което правех няколко пъти, след което пребазирах стъпките на сливане и смачках всички ангажименти. Трябва да има проблем с промяната на хеша или ангажиментите да бъдат смачкани неправилно.

По-добра практика би била новото базиране на новия клон към допълнителния комит на по-стария клон, така че историята на ангажиментите да е линейна (вместо сливане на H в G).

             0feature    1feature
                |           |
                v           |
A --  B -- C -- D -- H      |
                 \          v
                  E -- F -- G

С други думи, с горната схема, ако направя допълнителен ангажимент H към D (което ще премести указателя на 0feature към H), след това обединя 0feature в 1feature (и направя това няколко пъти), след което се опитам да пребазирам/sqash цялата история между 0feature и 1feature щях да имам проблеми. Вместо git checkout G; git merge H трябваше да използвам git rebase --onto H D G за всяко от малките почиствания. Правя втората от тези опции от първоначалния пост и оттогава съм добре.

Освен това, ако това беше моят дневник за ангажиране:

990cfb1 combine dump, add prog, combine validate
41013a9 Merge branch '5flash_addr' into 6flash_bankcheck
6f5e8f1 nothing interesting
7b8140d nothing interesting
2347714 implementation of dump and program

и пребазирам от 2347714, опцията за пребазиране трябва да изглежда така:

pick 7b8140d nothing interesting
s 6f5e8f1 nothing interesting
s 41013a9 Merge branch '5flash_addr' into 6flash_bankcheck
s 990cfb1 combine dump, add prog, combine validate
person swinman    schedule 18.06.2013