2012-02-01 12 views
9

Mam proste repozytorium z historią liniowej zatwierdzeń, jak:Jak ponownie zastosować zatwierdzenia na niepowiązanym oddziale?

[A] -> [B] -> [C] -> [D] -> [E] ... 

I w zasadzie trzeba usunąć popełnia A i B, więc pomyślałem, że tworzenie nowego repozytorium i chciałby osiągnąć coś takiego:

[X] -> [C] -> [D] -> [E] ... 

Więc stworzyłem nowego repozytorium, ręcznie utworzonego popełnić X, które odbywają przechowuje istotne informacje z punktu a i B i trzeba teraz polecenie, które przyniesie zobowiązuje C, D, E itd od oryginalnego repozytorium i położy to na moim nowym zatwierdzeniu X.

Jak to zrobić?

Edit: dwa problemy mam z sugerowanym sposobem cherry-pick to:

  1. Przeniesione zobowiązuje straciło dat. Czy istnieje sposób na zachowanie dat zatwierdzenia?
  2. Po pobraniu wzorca z oryginalnego repozytorium (i że zdalny wzorzec nie ma żadnego wspólnego z nowym repozytorium), mam problem z usunięciem tych pobranych zatwierdzeń. Kiedy robię git branch -D myoriginalrepo/master, mówi, że nie istnieje taka gałąź, podczas gdy ja wyraźnie widzę te zatwierdzenie w moim narzędziu GUI.
+0

Myślę, że powinieneś spojrzeć na git-pick-pick. –

+0

Czy kiedykolwiek zastanawiałeś się, jak nie zmieniać terminów? – thinsoldier

Odpowiedz

15

Nie wiem, dlaczego trzeba datę popełnienia pozostać taka sama, ale tu idzie:

git rebase B E --onto X --committer-date-is-author-date 

Jeśli B..E nie są w tym samym repozytorium jako X (ponieważ mogą one być if you create your fresh start in-place), trzeba je najpierw sprowadzić:

git fetch <path_to_old_repos> 

Oczywiście B, E i X tu na myśli ich popełniania-ID, jeśli nie zostały faktycznie określili/ich rozgałęzione.

Można też zrobić coś podobnego (choć datę popełnienia nie zostaną zachowane) przez przebazowania z A w oryginalnym repozytorium i zgniecenia B na nią:

git rebase -i `A` 

# change "pick b" to "squash b" 

Dostaniesz szansę zmienić popełnić wiadomość, w którym momencie możesz ją ustawić jako X.

+0

To brzmi jak najlepsze podejście do tej pory, jednak mam problem z pracą z zatwierdzeniami pobranymi za pomocą 'git fetch'. Jak mam się do nich odwoływać? Nie są w żadnej gałęzi, prawda? – Borek

+2

'git fetch' utworzy dla ciebie gałąź wygody o nazwie' FETCH_HEAD', która wskaże na wszystko, co "HEAD" było (to co zostało wyewidencjonowane) w twoim starym repozytorium. Co więcej, commit-ids będzie dokładnie taki sam dla repozytoriów, więc możesz po prostu przejść na przykład na 'git log '. Możesz także wybrać odpowiednią gałąź podczas pobierania: 'git fetch their_branch: my_branch'. – antak

3

Można użyć git cherry-pick. W twoim przypadku:

git cherry-pick C D E 

podczas gdy X to twoja głowa powinna to zrobić.

+0

Dzięki, pomyślałem, że to rebase będzie moim przyjacielem, ale wybór wiśni to polecenie do użycia. Mam nadzieję, że mogę określić zatwierdzenia takie jak "C ..", ponieważ mam ich setki w oryginalnym repo. – Borek

+0

Jeśli masz dużo, istnieje kilka opcji, które pozwolą ci je pogrupować. Sprawdź dokumentację. Rebase również zadziała - jeśli użyjesz go w oryginalnym repozytorium, aby zastąpić A i B przez X, otrzymasz taki sam wynik, jakiego szukasz. –

+1

Cherry pick wydaje się tracić informacje o dacie commitów (prawdopodobnie tworzy nowe zatwierdzenie), czy problem będzie taki sam z rebase? To byłoby dość złe, muszę zachować daty zatwierdzenia. – Borek

1

Mówisz, że utworzyłeś "nowe repozytorium". Prawdopodobnie nie chcesz tego zrobić. Jeśli z jakiegoś powodu commity A i B muszą całkowicie przestać istnieć (np. Z przyczyn prawnych lub przypadkowo popełniłeś swój numer karty kredytowej i tajny przepis na haggis) w twoim repozytorium, musisz przeczytać o tym, jak trwale usunąć zatwierdzenie . Ale najpierw naprawmy resztę drzewa.

Spróbuj czegoś podobnego

git checkout -b freshstart A 
# modify the state of the system until it reflects your desired new beginning X 
git commit --amend 
git cherry-pick C D E 

Teraz masz oddział o nazwie freshstart która ma swój początek i nowy X zobowiązuje C, D i E, zakładając, że scalanie ładnie na X.

+0

To prawda, że ​​A i B muszą zostać całkowicie usunięte z historii, więc stworzenie nowego repozytu wydaje się być dobrym sposobem na rozpoczęcie. Stworzyłem stan X, pobraną zdalną gałąź original-repo/master, a teraz mogę cherry pick commit z niego do głównej gałęzi. Mam dwa problemy: 1) Wybrane przez Cherry commity tracą swoją datę 2) Nie mogę odwoływać się do oryginalnego repo/master branch (ponieważ nie ma on żadnego wspólnego rodzica z lokalnym master i stoi obok mojego "master" chyba). Nie mogę usunąć tej tymczasowej gałęzi, którą wybrałem. – Borek

+1

Nie potrzebujesz nowego repozysu, aby całkowicie usunąć zatwierdzenia. Możesz użyć rebase, na przykład, aby wyeliminować zatwierdzenia. Jedyną rzeczą jest to, że jeśli masz powody prawne lub coś do usunięcia commitów, upewnij się, że obiekty, które stają się odpadami podczas usuwania zatwierdzeń, zostaną wyczyszczone, aby nie były dostępne dla osób, które wiedzą, co robią. I oczywiście musisz się udać do każdego klona repozytu wszędzie i zrobić to samo, albo możesz nie wywiązać się z obowiązku prawnego. – bames53

+0

A i X nie mają wcześniejszych wspólnych zobowiązań, czy można utworzyć oddział, który nie ma rodzica w moim oryginalnym repo? – Borek

Powiązane problemy