2011-01-07 21 views
78

Biorąc pod uwagę, że istnieje kilka poleceń git, że nie ma sensu w gołego repozytorium (bo gołe repozytoria nie używać indeksów i nie mają katalog roboczy),Jak mogę nie akceptować ostatniego zatwierdzenia w repozytorium git bare?

git reset --hard HEAD^ 

nie jest rozwiązaniem uncommit ostatnia zmiana w takim repozytorium.

przeszukując Internet, wszystko udało mi się znaleźć związane z tematem jest this, w której jestem przedstawił trzy sposoby robienia tego:
1. „zaktualizować ref ręcznie (co wiąże się hydrauliką)”;
2. "git push -f z non-bare repozytorium";
3. "git branch -f this $that".

Które z rozwiązań uważasz za bardziej odpowiednie lub jakie są inne sposoby, aby to zrobić? Niestety, dokumentacja, którą znalazłem na temat repozytoriów git bare jest dość słaba.

+7

@ Lavinia-Garbriela Dobrovol Nie używaj skomplikowanych rzeczy poniżej. Próbujesz przenieść HEAD do innego zatwierdzenia i właśnie do tego jest przeznaczony reset git, nawet w przypadku gołego repo. Za moją odpowiedź poniżej, użyj: git reset --soft Z --soft, nie próbuj zmieniać działającego drzewa i indeksu, który nie istnieje, więc git pozwala ci zresetować bez problemu. – Hazok

Odpowiedz

107

Można użyć polecenia git update-ref. Aby usunąć ostatni popełnić, byłoby użyć:

$ git update-ref HEAD HEAD^ 

Lub jeśli nie jesteś w branży, z którego mogę usunąć ostatni popełnić:

$ git update-ref refs/heads/branch-name branch-name^ 

Można również przekazać SHA1 if chcesz:

$ git update-ref refs/heads/branch-name a12d48e2 

Zobacz dokumentację polecenia git-update-ref.

+0

Co to jest HEAD na nagim repo nie jest na prawym oddziale? – VonC

+0

@ Lavinia-Gabriela Dobrovolschi: prawda, nie byłam zaznajomiona z dokładną składnią. – VonC

+0

@VonC Możesz określić w 'git update-ref ' na przykład w prawej gałęzi, na przykład "refs/heads/master" zamiast HEAD. Mam nadzieję, że źle zrozumiałem twoje pytanie. –

7

git push -f powinny działać prawidłowo:
jeśli sklonować że goły repo, usunąć ostatni commit (git reset --hard HEAD^ jak wspomniałeś, ale w lokalnym zakaz nagiej repo) i odepchnąć (-f):

  • nie zmieniasz żadnego SHA1 dla innych commitów poprzedzających ten, który usuniesz.
  • jesteś pewien, że cofasz dokładną treść nagłego repo minus dodatkowy commit (ponieważ po prostu sklonowałeś go jako pierwszy).
+0

@ VonC Witam Von, widziałem, że bardzo często odpowiadałeś na Gita, więc chciałem cię zapytać ... Byłem ciekawy, dlaczego nie miałbym "git zresetować --soft " jak pokazano w mojej odpowiedzi poniżej, być zalecaną praktyką do przenoszenia HEAD na nagim repo? – Hazok

+0

Przypuszczam, że innym powodem, dla którego pytam, jest to, że używanie miękkiego resetowania dla nagich repo to nie informacja, która jest łatwo dostępna i wiele forów wydaje się mieć niepotrzebnie skomplikowane obejścia, gdy wydaje się, że miękki reset jest najlepszą praktyką z powodu najmniejszej ilości pisania i najmniejszego wpisywania. szansa na błąd. – Hazok

+1

@Zach: 'reset --soft' powinien działać, gdy zostanie wykonany bezpośrednio na nagim repo. Podejrzewam, że rzadko się to zdarza, ponieważ nagie repo jest zazwyczaj ** repozytorium ** (tzn. Repo, do którego przesyłasz dane), a przez większość czasu * nie masz * bezpośredniego lokalnego dostępu do niego . Ale jeśli tak, to jest to z pewnością kolejny dobry przykład użycia '' reset --soft'' (jak w http://stackoverflow.com/questions/5203535/practical-uses-of-git-reset-soft). +1 do twojej odpowiedzi. – VonC

25

przypadku korzystania z następujących gołego repo:

git reset --soft <commit> 

wtedy nie napotkasz problemów masz użyciu --hard i --mixed opcje w gołego repo, ponieważ nie próbujesz coś zmienić nagie repozytorium nie ma (np. drzewo robocze i indeks).W twoim przypadku konkretnie co chcesz używać (od gołej repo):

git reset --soft HEAD^ 

Aby switch branches on the remote repo zrobić:

git symbolic-ref HEAD refs/heads/<branch_name> 
+2

Jak wybrać gałąź, którą chcesz przenieść? Twój przykład działa dobrze na master, ale 'git checkout other_branch' nie działa w gołym. – Gauthier

+1

Hmmm ... Zastanawiam się, kto głosował na mnie w tej sprawie. Pytanie nie pytało, jak przełączać gałęzie na zdalnym repo, pytało, jak zresetować na nagim repo. Aby zmienić domyślną gałąź w zdalnym repo, użyj git symbolic-ref HEAD refs/heads/. – Hazok

2

Można również użyć notacji refspec git i zrobić coś takiego:

git push -f origin +<commit you want to revert to>:<destination_head | branch_name>

Wymusza aktualizację gałęzi docelowej (zgodnie z oznaczeniem ref) do zatwierdzenia źródłowego zgodnie z oznaczeniem +<object ref> część.

+2

z wyjątkiem sytuacji, gdy na gałęzi znajduje się acl - co zwykle ma miejsce, jeśli "musisz to zrobić na samym repozytorium" ... –