Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: git push wybranego commita a nie wszystko
Forum PHP.pl > Forum > Kontrola i zarządzanie projektami
nospor
Hej, jak w git mogę zrobić push do wybranego repozytorium ale push tylko wybranego commita lub wybranych commitow a nie wszystkich?
Po co mi to? Załóżmy że mam repozytorium core, z ktorego korzystają wszystkie nowe projekty. I gdy np. rozwijam projekt 3 i zrobie tam zmianę, która jest uniwersalna i ważna i powinna się znaleźć w innych projektach. Chcę więc ją wrzucic do core, by inny projekty mogły z tamtąd te ważną zmianę pociągnąć. Nie chcę jednak wrzucać innych commitow, ktore robiłem w projekt 3, gdyż one są zbędne w innych projektach
tzm
Kiedyś jak sobie wyrabiałem swój workflow który nie koniecznie pasował innym programistą z racji 12 tysięcy plików z node chciałem zrobić coś podobnego i niestety doszliśmy do wniosku że tak się nie da i powinno się raczej tworzyć submoduły które można dołączyć do wybranych projektów i opcjonalnie dociągać, innej drogi niestety nie znaleźliśmy więc podpinam się, może akurat ktoś zna rozwiązanie

@down, nospor : nie dziwie sie ze nikt u mnie nie wiedzial jak to poskladac.. biggrin.gif jak nie wybuchlo to potestuje na jakims testowym repo, dzieki
nospor
Aktualnie bawie się z branchami i cherry-pick. Byc moze to bedzie to. Jak obadam, dam znac

edit: dobra, mam:
By zrobic to co pisalem, to po zrobienia komitow w projekt 3, robie
1) nową galąż w projekt 3
2) pushuje tę gałąź do core
3) w core bedąc w master (bo chce to miec w galezi master) robie
git cherry-pick hashcommit
gdzie hashhcommit to hash commita z nowej galęzi, z ktorej chciałęm pobrac zmiany

I dziala smile.gif
pyro
Co prawda cherry-pick zadziała do tego co mówisz (pozwala na aplikowanie konkretnych commitów), ale Twój opis świadczy o tym, że na 80-90% popełniasz błąd w przepływie pracy, więc pewnie chciałbyś jeszcze raz przeanalizować, to co chcesz zrobić wink.gif

// ADD

Poza tym nie ten dział. Forum: Kontrola i zarzadzanie projektami . Przenoszę i zamykam temat.
nospor
Faktycznie, nie ten dzial. Przenosze i nie zamykam wink.gif

Skoro uwazasz, ze popelniam blad, chetnie wyslucham na czym on polega. Ewentualnie jak wg. Ciebie powinienem poprawnie zrealizować to co napisałem?
tzm
sugestia że nospor chciałby to przeanalizować boska, też chętnie poczytam sugestii pyro bo mam tożsamy problem.
pyro
Z opisu wyżej nie wywróżę struktury Twojego projektu i zmian, które wprowadzasz smile.gif . W praktyce jednak cherry-pick używa się bardzo rzadko i najczęściej wynika to z błędu początkującego. Pracując nad kilkoma wielomiesięcznymi, z n-tysiącami commitów, projektami nie musiałem go użyc ani razu.
nospor
pyro czyli chyba nie zrozumiales tego co napisalem. Nie wiem jak to opisac bardziej czytelniej.
pyro
Jeżeli przeczytasz jeszcze raz pierwszy post tematu, to jednak chyba przyznasz, że jest to dość ogólny opis sytuacji, do którego ciężko dopasować konkretne rozwiązanie. Na jego podstawie ciężko nawet stwierdzić czy jest to problem natury obycia z GITem, czy może organizacji projektów.

Może jakiś przykład?
nospor
Wiekszosc moich projektow ma ten sam "core", czyli kod, ktory jest wpólny dla nich wszyskich: logowanie, rejestracja, zarządzanie uzytkownikami itp.
Czyli kazdy nowy projekt startuje na podstawie "core"

Zalozmy, ze mam projekty:
pr1
pr2
pr3
Wszystko startowały z "core". Każdy z nich rozwijam. I teraz nagle w pr3 zrobiłem coś, co po przemyśleniu okazuje się, żę powinno znaleźć się w "core", gdyż jest to funkcja, która docelowo powinna być we wszystkich projektach. Wiec do "core" chciałbym wrzucić tylko zmiany z danego commita, a nie wszystkie zmiany ktore robiłem w pr3 gdyż inne zmiany są typowe tylko dla pr3 i mają się nijak do innych projektów. Ale akurat ta jedna zmiana, co teraz zrobilem, jest na tyle ciekawa, ze chciałbym by była wszędzie.

edit: to co zrobilem teraz na branchu i cherry-pick można też zrealizować przy pomocy patchy
pyro
W takim razie ten "core" to jakiś zbiór gotowych narzędzi? Nie możesz w takim razie dołączać go do swoich projektów jako submoduł?
nospor
Nie, core to nie jest zbior narzedzi. core to core.

Jak masz fundamenty budynku, to one są fundamentami budynku, a nie garazem obok smile.gif Dom budujesz na fundamencie, tak jak ja aplikacje buduje na core a nie obok.
pyro
Core jako core też może być submodułem wink.gif
nospor
Tak, ale akurat nie w tym przypadku.
Rozumiem o czym mowisz, mam też takie "narzędzia", które leżą obok i z nich korzystają wszystkie projekty. Ale core w moim przypadku jest dość specyficzny i dlatego robie jak robie. Znalazłem na to dwa sposoby:
branch z cherry-pick lub patche
osiągnąłem co chciałem smile.gif
Pyton_000
No taa ale już Kto Ci pomagał to ja nie powiem tongue.gif

Co do submodułów @pyro to ja nie jestem zwolennikiem. Jakoś mi to nie leży.
pyro
Cytat(Pyton_000 @ 17.03.2015, 22:03:59 ) *
Co do submodułów @pyro to ja nie jestem zwolennikiem. Jakoś mi to nie leży.


Ja też nie. Jak dla mnie paczki powinny być paczkami i co prawda submoduł może być taką paczką, ale są do tego lepsze narzedzia, np. composer

com
No tak, @pyro niektórzy są jeszcze niezreformowani biggrin.gif
nospor
Cytat
No taa ale już Kto Ci pomagał to ja nie powiem
Tja.... w tym temacie wypowiedziales się jak juz bylo po wszystkim.... wink.gif
No dobra, twoje prywatne wskazówki byly nieocenione smile.gif
vokiel
@nospor czyli Ty budujesz aplikację na core (modyfikując je/go), nie używasz go jako core nietykalnego, tak?

Jeśli core byłby nietykalny - czyli całkowity zakaz modyfikacji w obrębie projektu - dopuszczone tylko jego rozszerzanie (już w obrębie budowanej aplikacji). Wtedy byś mógł go łatwo wersjonować: core v1.0, core v1.0.1 itd.

Przy PR3 stwierdzasz, że dobrze byłoby coś dodać do samego core dla reszty projektów. Robisz wtedy nową wersję core i aktualizujesz ją w innych projektach. IMHO core powinieneś traktować jak każdą inną paczkę, np z composer'a.
nospor
Cytat
@nospor czyli Ty budujesz aplikację na core (modyfikując je/go), nie używasz go jako core nietykalnego, tak?
Tak, kazdy projekt moze go sobie zmodyfikowac pod wlasne potrzeby.

Cytat
Jeśli core byłby nietykalny - czyli całkowity zakaz modyfikacji w obrębie projektu - dopuszczone tylko jego rozszerzanie (już w obrębie budowanej aplikacji). Wtedy byś mógł go łatwo wersjonować: core v1.0, core v1.0.1 itd.

Przy PR3 stwierdzasz, że dobrze byłoby coś dodać do samego core dla reszty projektów. Robisz wtedy nową wersję core i aktualizujesz ją w innych projektach. IMHO core powinieneś traktować jak każdą inną paczkę, np z composer'a.

Hmm... jest to jakis pomysł. Jednak przy obecnej strukturze jaką mam, moze z tym być problem. Ale jak w przyszlosc bede zmieniał, będę miał to na uwadze smile.gif
com
Najlepiej przebudować to już na tym etapie i oszczędzić sobie późniejszych problemów, bo tak zaraz się okaże, że w każdym z projektów wersję Ci się core rozejdą w rożne strony i będziesz miał z tym problem. Tak jak już powiedziano zrób sobie to tak, core czyli ten fundament wypuszczasz jako zależność dla wszystkich projektów i nie wkomponowujesz całego jego kodu do projektu a dociągasz z repo core. Każda modyfikacje która wiesz że chcesz wkomponować do wszystkich projektów pisz w samym projekcie core a do jego potomków dociągniesz sobie kolejną wersje wraz z tą modyfikacją, wtedy problem z tego wątku znika. Tym bardziej, że jak sam zauważyłeś to jest kwestia jednego/paru commitów. Wtedy masz nad wszystkim łatwą kontrole i samo core może być mniej lub bardziej rozbudowane wedle potrzeb danego projektu. smile.gif
nospor
Cytat
Najlepiej przebudować to już na tym etapie i oszczędzić sobie późniejszych problemów, bo tak zaraz się okaże, że w każdym z projektów wersję Ci się core rozejdą w rożne strony i będziesz miał z tym problem
Sytuacja, gdzie zmieniam core zdarza sie rzadko, ale sie zdarza. Przebudowywanie tego zajmie mi zdecydowanie wiecej czasu.
Co do rozjezdzania nie bedzie problemu. Przez lata tak pisalem projekty na SVN i jakos sie nie rozjedzalo smile.gif Teraz przeszedlem na GIT i chcialem sie dowiedziec jak to moge zrobic w GIT to co robilem w SVN.

Ale jak juz mowilem: przy nowych projektach w nowej architekturze bede miał to na uwadze.
com
ok, w porządku smile.gif
to zależy jak na to spojrzeć. Bo tak defakto właśnie problem, który tu wyniknął jest już kwestią tego, że to co stworzyłeś w pr3 i ma się pojawić teraz również w pr2 i 1 jest rozjazdem. Kiedy zarządzasz wszystkim sam i masz wiedzę o całym projekcie to to kontrolujesz, ale na pewno zdarza Ci się, że jednak musisz do każdego z nich zajrzeć i sprawdzić aha tego mi tu brakuje. Jak nie teraz to za pół roku kiedy masz jakaś dłuższa przerwę smile.gif

Ale rozumiem, że przebudowa tego była by kłopotliwa i z tym się nie spieram smile.gif
pyro
@nospor, wcześniej podałeś przykład

Cytat(nospor @ 17.03.2015, 20:53:08 ) *
Wiekszosc moich projektow ma ten sam "core", czyli kod, ktory jest wpólny dla nich wszyskich: logowanie, rejestracja, zarządzanie uzytkownikami itp.


I akurat te wszystkie funkcje posiada np. UserBundle z FOS bundles od Symfony. Instaluje się go composerem, a jego kod można nadpisywać przy każdym projekcie pod indywidualne potrzeby bez modyfikacji w oryginale, tj. w vendor. W wolnej chwili polecam ściągnąć sobie Sf z tym bundlem i obadać jak jest zrobiony, bo na ten moment wychodzi, że jednak to był błąd zarówno w organizacji projektu, jak i obycia z GITem wink.gif
nospor
Cytat
I akurat te wszystkie funkcje posiada np. UserBundle z FOS bundles od Symfony.
Tak, ale ja tylko wymienilem tam małą cześć core. Sklada sie on jeszcze z masy innych rzeczy o innej strukturze.

Cytat
W wolnej chwili polecam ściągnąć sobie Sf z tym bundlem i obadać jak jest zrobiony, bo na ten moment wychodzi, że jednak to był błąd zarówno w organizacji projektu, jak i obycia z GITem
Alez nie mowie że nie. Strukture tego co mam teraz zrobilem wieki temu, gdy jeszcze nikt nie slyszal o bundlach, composerach itp.
Zas co do GITa to bawie sie z nim od tygodnia na serio wiec.... smile.gif Nie mniej jednak uwazam, że GITa już kumam, swiadczy o tym fakt, ze udalo mi sie zrobic co chciałem biggrin.gif
Nattfarinn
Nie chce być Evil NecroPosterem (ale nie przesadzajmy, temat nie jest ani stary ani zamknięty), ale tak generalnie to gitem da się załatwić to tak, by było wygodne i nie jest to taka czarna magia. Linus Torvalds wszystko przewidział. smile.gif

Zakładam, że masz repozytoria per projekt oraz core. Załóżmy, że wygląda to tak (nie wiem czy to Twój user, ale użyję dla przykładu):

Core: https://github.com/nospor/core.git
Cucumber (projekt 1): https://github.com/nospor/cucumber.git
Potato (projekt 2): https://github.com/nospor/potato.git

U siebie, w swoim lokalnym repozytorium (np. potato) tworzysz brancha 'core' i ustawiasz mu upstream na repozytorium https://github.com/nospor/core.git (branch master).

Rozwijasz aplikację potato na swoich feature branchach lub na masterze, jak lubisz. Jeśli napiszesz coś, co chciałbyś mieć w 'core' to cherry-pick na branch 'core' jest jak najbardziej wskazany (do tego służy), ale najpierw upewniasz się czy branch 'core' jest aktualny (mógł zostać zmieniony bezpośrednio, lub też napisałeś coś fajnego przy okazji cucumbera): 'git checkout core && git pull --rebase'. Jeśli wszystko jest OK, to cherry-pickujesz zmianę którą chcesz 'git cherry-pick hash_commit'. Pushujesz zmiany do remote repozytorium (lądują w 'https://github.com/nospor/core.git', bo taki jest tego brancha upstream). Zakładasz, że każdy projekt bazuje na 'core' (słowo bazuje jest tutaj kluczowe). To teraz musisz zmienić bazę swoich projektów, bo 'core' się zmienił. Robisz to też dla projektu na którym feature dla 'core' powstał, żeby spójną kolejność commitów: na spodzie core, na górze projekt. Załatwiasz to w bardzo prosty sposób. Będąc w lokalnym repo swojego projektu (potato, cucumber) zaciągasz najnowszego 'core': 'git checkout core && git pull --rebase', a następnie na swoim branchu zmieniasz 'bazę' na 'core': 'git rebase core'. Rozwiązujesz potencjalne konflikty, jeśli takie się pojawiły (potato może się mocno różnić od cucumbera), ale finalnie masz zachowaną spójną strukturę: baza 'core' na dole, zmiany projektowe na górze. Pamiętaj tylko, że po zmianie bazy zwykły 'git push' nie zadziała (bo lokalne i remote repozytoria różnią się bazą, a jak zmienia się baza to zmieniają się hashe wszystkich commitów nad bazą i git Ci odrzuci taką próbę). Takiego pusha robisz to za pomocą 'git push --force'. Rebase to potężne narzędzie w gicie i stosowane ostrożnie i z rozwagą daje cudowne efekty.

PS. Zaraz to opiszę w formie lekkostrawnej, bo blok tekstu może przerażać, ale finalnie to bardzo prosta a bardzo użyteczna rzecz.
nospor
No tego --rebase to przyznaje się bez bicia jeszcze nie kumam i omijam szerokim łukiem. Póki co nie był potrzebny.

Cytat
U siebie, w swoim lokalnym repozytorium (np. potato) tworzysz brancha 'core'
Jak w danej chwili zrobi brancha core, to on bedzie miał zawartosc mojego projektu z danej chwili. Zakładam wiec, ze tego brancha należy utworzyć zaraz po stworzeniu gita projektu, czyli zaraz po clone, gdyż tylko wtedy ma to jakikolwiek sens, dobrze myśle?
Nattfarinn
Możesz to zrobić w dowolnym momencie. W skrócie, robisz to tak:

Kod
$ cd /path/to/local/repository
$ git remote add core git@github.com:core.git     # dodaje kolejne repozytorium remote i nazywa je core
$ git fetch core
$ git checkout -b core core/master                # przełącza Cię na nieistniejącego jeszcze lokalnie brancha o nazwie core z upstreamem core/master


I w sumie tyle. Branch 'core' tak naprawdę prowadzi do brancha 'master' repozytorim 'git@github.com:core.git'

Jak napiszesz na branchu 'myfeature' jakiś feature który chciałbyś wrzucić do 'git@github.com:core.git':

Kod
$ git checkout core
$ git pull --rebase               # zaciągnij zmiany przenosząc niepushnięte dotąd zmiany na samą górę
$ git cherry-pick hash_commita
$ git push
$ git checkout myfeature
$ git rebase core                 # zmień bazę swojego brancha na core


To ostatnie polecenie jest po to, żebyś miał 'core' na dole, a wszystkie swoje zmiany projektowe na górze. To powinno wywalić commit który cherry-pickowałeś, bo nie jest już potrzebny (jest częścią 'core'). Tylko musisz pamiętać, że jeśli Twój projekt dorobił się tysięcy commitów, to zmiana bazy 'core' może trochę potrwać. To wygląda tak, że git commit po commicie nakłada Twoje zmiany na bazę. To może spowodować konflikty, jeśli commit który cherry-pickowałeś jest zależny od struktury którą zbudowałeś dopiero w projekcie, ale to oczywiste. Jeśli w pewnym momencie zatrzyma Ci się rebase na konflikce, to po konflikcie nie zaczynasz procesu od nowa (bo dalej 'trwa' rebase) tylko kontynuujesz od miejsca w którym się zatrzymało przez polecenie:

Kod
$ git rebase --continue


Może się też zdarzyć, że proces rebaseowania zatrzyma Ci się w momencie commitu który cherry-pickowałeś. Tutaj po prostu nie dam sobie głowy uciąć, bo zwyczajnie nie pamiętam, czy git załatwi to sobie automatycznie i pominie pusty commit czy też powie Ci, że commit jest pusty (bo zmiany przez tego nakładane zostały już nałożone wcześniej). Jeśli to drugie, to ignorujesz commit jako niepotrzebny poleceniem:

Kod
$ git rebase --skip


Więcej Ci nie potrzeba w sumie. smile.gif

Edit: Jeśli rebase nie idzie po Twojej myśli, konfliktów pełno i końca nie widać, to zawsze możesz go przerwać za pomocą:

Kod
$ git rebase --abort


To w ułamku sekundy przywróci Ci stan sprzed polecenia rebase.

Ogólnie rebase to najpotężniejsze narzędzie jakie stoi za gitem. Za tydzień nie będziesz mógł bez niego żyć. Przenoszenie, łączenie, zmiana nazw commitów jest mega wygodna za pomocą trybu rebase interactive.
nospor
Dzieki, pobawie sie jeszcze tym sposobem smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.