Scal (za pomocą squasha) wszystkie zmiany z innej gałęzi jako pojedynczy commit

W Git, czy istnieje sposób na scalenie wszystkich zmian z jednej gałęzi do drugiej, ale squash do jednego commita w tym samym czasie?

Często pracuję nad nową funkcjonalnością w oddzielnej gałęzi i będę regularnie commit / push-głównie w celu tworzenia kopii zapasowych lub przeniesienia tego, nad czym pracuję na inną maszynę. Głównie te commity mówią "funkcja xxx WIP" lub coś zbędnego.

Gdy ta praca zostanie zakończona I chcę połączyć gałąź WIP z powrotem do master, chciałbym odrzucić wszystkie te pośrednie commity i tylko a mają jeden czysty commit.

Czy jest na to łatwy sposób?

Alternatywnie, co powiesz na polecenie, które zgniata wszystkie commity na gałęzi od punktu, w którym została rozgałęziona?

 511
git
Author: ux.engineer, 2010-09-12

8 answers

Inną opcją jest {[0] } następnie wykonaj git commit.

From Git merge

--squash

--no-squash

Tworzy drzewo robocze i stan indeksu tak, jakby prawdziwe scalenie stało się (z wyjątkiem połączenia informacji), ale faktycznie nie sprawiają a commit or move the HEAD, nor record $GIT_DIR/MERGE_HEAD aby spowodować następne git commit polecenie utworzenia połączenia / align = "left" / Pozwala to na stworzenie pojedynczy commit na szczycie bieżącego gałąź, której efektem jest tak samo jak łączenie innej gałęzi (lub więcej w przypadek ośmiornicy).

 636
Author: fseto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 02:48:26

Znalazłem! Polecenie Merge posiada opcję --squash

git checkout master
git merge --squash WIP

W tym momencie wszystko jest połączone, prawdopodobnie skonfliktowane, ale nie popełnione. Więc teraz mogę:

git add .
git commit -m "Merged WIP"
 230
Author: Brad Robinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-13 00:26:17

Spróbuj git rebase -i master w swojej gałęzi funkcji. Następnie możesz zmienić wszystkie oprócz jednego 'pick' na 'squash', aby połączyć commity. Zobacz zgniatanie commitów za pomocą rebase

Na koniec możesz wykonać merge z gałęzi master.

 32
Author: fseto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-13 00:14:21

Użycie git merge --squash <feature branch> jako zaakceptowanej odpowiedzi sugeruje, że robi sztuczkę, ale nie pokaże połączonej gałęzi jako faktycznie połączonej.

Dlatego jeszcze lepszym rozwiązaniem jest:]}
  • tworzy nową gałąź z najnowszego master, commit w gałęzi master, w której gałąź feature została zainicjowana.
  • połącz <feature branch> z powyższym używając git merge --squash
  • Połącz nowo utworzoną gałąź w master. W ten sposób gałąź feature będzie zawierać tylko jeden commit połączenie będzie przedstawione na krótkiej i uporządkowanej ilustracji.

Ta wiki szczegółowo wyjaśnia procedurę.

W poniższym przykładzie zrzut ekranu z lewej strony jest wynikiem qgit, A zrzut ekranu z prawej strony jest wynikiem:

git log --graph --decorate --pretty=oneline --abbrev-commit

Oba zrzuty ekranu pokazują ten sam zakres zmian w tym samym repozytorium. Niemniej jednak właściwy jest bardziej zwarty dzięki --squash.

  • z biegiem czasu, master Oddział odchylił się od db.
  • Kiedy funkcja db była gotowa, nowa gałąź o nazwie tag została utworzona w tym samym commicie master, który db ma swój root.
  • Z tag a git merge --squash db został wykonany, a następnie wszystkie zmiany zostały zainscenizowane i popełnione w jednym commicie.
  • od master, tag połączono: git merge tag.
  • gałąź {[17] } jest nieistotna i nie łączy się w żaden sposób.

Tutaj wpisz opis obrazka

 8
Author: raratiru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-12 17:45:36

Stworzyłem swój własny alias git, aby to zrobić. Nazywam to git freebase! Pobierze istniejącą brudną, niewybaczalną gałąź funkcji i odtworzy ją tak, że stanie się nową gałąź o tej samej nazwie z commitami zgniecionymi w jeden commit i zmienionymi na podaną gałąź (domyślnie master). Na samym końcu, pozwoli Ci użyć dowolnej wiadomości commit, którą lubisz dla swojej nowej gałęzi "freebased".

Zainstaluj go, umieszczając następujący alias w Twoim .gitconfig:

[alias]
  freebase = "!f() { \
    TOPIC="$(git branch | grep '\\*' | cut -d ' ' -f2)"; \
    NEWBASE="${1:-master}"; \
    PREVSHA1="$(git rev-parse HEAD)"; \
    echo "Freebaseing $TOPIC onto $NEWBASE, previous sha1 was $PREVSHA1"; \
    echo "---"; \
    git reset --hard "$NEWBASE"; \
    git merge --squash "$PREVSHA1"; \
    git commit; \
  }; f"

Użyj go z gałęzi funkcji, uruchamiając: git freebase <new-base>

Testowałem to tylko kilka razy, więc najpierw Przeczytaj i upewnij się, że chcesz go uruchomić. Jako mały środek bezpieczeństwa drukuje początkowy sha1, więc powinieneś być w stanie przywrócić starą gałąź, jeśli coś pójdzie nie tak.

Utrzymam to w moim dotfiles repo na GitHubie: https://github.com/stevecrozz/dotfiles/blob/master/.gitconfig

 3
Author: Stephen Crosby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-16 22:33:37

2020 zaktualizowano

Z flagą --squash wygląda jak dwie równoległe gałęzie bez relacji:

Tutaj wpisz opis obrazka

Sortowanie commitów związanych z datą wygląda następująco:

Tutaj wpisz opis obrazka

Osobiście nie lubię -- opcja squasha, spróbuj tej sztuczki, może pasuje do Twoich potrzeb, używam jej do małych projektów:

  1. git init
  2. git checkout-b dev
  3. kilka commitów w dev
  4. po wykonaniu kilku świetnych commitów w dev(ale nie scalonych z master yet), jeśli nie chcesz, aby wszystkie commity były kopiowane do gałęzi master, to celowo zmień coś w master and (dodaj kilka pustych linii w pliku README I commit w master),
  5. git merge dev Powoduje to konflikt scalania (puste linie w README), rozwiązywanie go, commit z nową wiadomością, którą chcesz, i gotowe. Oto jego wizualna reprezentacja.

Null commit for intentely merge conflict, name it anything you Preferred

null commit for intentely merge conflict

 3
Author: Akbar Pulatov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-27 08:31:39

git merge --squash <feature branch> to dobra opcja ."Git commit" wyświetla komunikat commit gałęzi z Twoim wyborem, aby go zachować .

For less commit merge .

Git merge do X times --GIT reset HEAD^ --soft następnie git commit .

Ryzyko-usunięte pliki mogą wrócić .

 -1
Author: Arjun Mullick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-06 04:10:13

Możesz to zrobić za pomocą polecenia "rebase". Nazwijmy gałęzie "main" i "feature":

git checkout feature
git rebase main

Komenda rebase powtórzy wszystkie commity na " feature "jako jeden commit z rodzicem równym"main".

Możesz chcieć uruchomić git merge main przed git rebase main, Jeśli "main "zmienił się od czasu utworzenia" feature " (lub od ostatniego scalenia). W ten sposób, nadal masz pełną historię na wypadek konfliktu scalenia.

Po rebase, możesz scalić swoją gałąź do main, co powinno skutkować szybkim połączeniem:

git checkout main
git merge feature

Zobacz rebase Strona zrozumienie Gita koncepcyjnie dla dobrego przeglądu

 -5
Author: NamshubWriter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-13 00:25:09