Zmień zdalne HEAD w Git, aby wskazywał coś innego niż master


124

Jak ustawić odwołanie HEAD pilota Git tak, aby wskazywało na coś innego niż „master”?

W moim projekcie obowiązuje zasada nieużywania gałęzi „master” (wszystkie gałęzie mają mieć zrozumiałe nazwy). Co więcej, kanoniczne repozytorium główne jest dostępne tylko przez ssh: //, bez dostępu do powłoki (jak GitHub lub Unfuddle).

Mój problem polega na tym, że zdalne repozytorium nadal ma odniesienie HEAD do refs / heads / master, ale potrzebuję go, aby wskazywał na inną gałąź. Powoduje to dwa problemy:

  1. Podczas klonowania repozytorium

    ostrzeżenie: zdalne HEAD odnosi się do nieistniejącego ref, niezdolnego do pobrania.

    To zagmatwane i niewygodne.

  2. Internetowa przeglądarka kodu opiera się na HEAD jako podstawie przeglądania drzewa. W takim razie potrzebuję HEAD, aby wskazać prawidłową gałąź.


Właśnie dodałem jedną możliwość dla rekordu, ale nie nadaje się do twojego przypadku.
VonC

Sztuczka „bez wspólnego przodka”: interesująca. Możesz opublikować ją jako szczegółową odpowiedź i wybrać ją jako oficjalną, jeśli uznasz, że działa.
VonC

12
FWIW, ponieważ wspomniałeś o GitHubie w pytaniu - jeśli chcesz zmienić referencję HEAD na GitHubie, po prostu przejdź do ekranu „Administrator” repozytorium i zmień listę rozwijaną „Domyślna gałąź” na dowolną gałąź, na którą ma wskazywać HEAD.
Joe


Odpowiedzi:


63

Prawie to samo pytanie pojawiło się rok temu na GitHubie .

Pomysł polegał na zmianie nazwy gałęzi głównej:

git branch -m master development
git branch -m published master
git push -f origin master 

Sprawianie, że mistrz ma to, czego chcesz, aby ludzie używali i wykonuj wszystkie inne prace w gałęziach.

(„ git-symbolic-ref HEAD refs/head/published” nie zostanie przeniesiony do zdalnego repozytorium)

Jest to podobne do „ Jak usunąć źródło / wzorzec w Git ”.


Jak powiedziano w tym wątku : (moje podkreślenie)

git clone” tworzy tylko jeden oddział lokalny.
Aby to zrobić, patrzy na HEAD refzdalne repozytorium i tworzy lokalną gałąź o tej samej nazwie, co zdalna gałąź, do której się odwołuje.

Podsumowując, masz repozytorium A i sklonuj to:

  • HEADreferencje refs/heads/masteri istnieje
    -> otrzymujesz lokalną gałąź zwaną master, zaczynającą się od źródła / wzorca

  • HEAD refs/heads/anotherBranchi że istnieje
    -> otrzymujesz lokalny oddział o nazwie anotherBranch, zaczynający się odorigin/anotherBranch

  • HEAD, refs/heads/mastera to nie istnieje
    -> narzeka "git clone"

Nie jestem pewien, czy istnieje sposób na bezpośrednią modyfikację HEADref w repozytorium .

(co jest sednem twojego pytania, wiem;))


Może jedynym sposobem byłaby „publikacja dla biednych” , w której:

 $ git-symbolic-ref HEAD refs/head/published
 $ git-update-server-info
 $ rsync -az .git/* server:/local_path_to/git/myRepo.git/

Ale wymagałoby to dostępu do zapisu na serwerze, co nie zawsze jest możliwe.


Jak wyjaśniam w „ Git: poprawny sposób zmiany Active Branch w czystym repozytorium? ”, git remote set-headNie zmieniłbym niczego w zdalnym repozytorium.

Zmieniłoby to tylko gałąź zdalnego śledzenia przechowywaną lokalnie w lokalnym repozytorium w remotes/<name>/HEAD.


Dzięki, VonC. Przeczytałem to przed wysłaniem tutaj. Ale jak widać, gałąź zwana „master” nie jest mile widziana w tym projekcie ze względów technicznych i politycznych.
JasonSmith

Możesz następnie wymusić tę zasadę, uniemożliwiając jakąkolwiek aktualizację w gałęzi głównej za pomocą zaczepu przed zatwierdzeniem.
VonC

Tak, jeśli okaże się, że nie ma sposobu, aby zrobić to, co chcę, to zrobię dokładnie to i przyjmuję twoją odpowiedź. Dziękuję za kontakt!
JasonSmith

Dziękuję za aktualizację. W tej chwili użyłem sztuczki „bez wspólnego przodka”, aby utworzyć gałąź główną z tylko jednym zatwierdzeniem. (To znaczy: git branch -D master; echo ref: refs / heads / master> .git / HEAD; rm *). Następnie po prostu dotknąłem pliku o nazwie GO_AWAY i komunikat zatwierdzenia wyjaśnia sytuację. Na razie to zadziała. Mogę sprawdzić źródło i wyśledzić, gdzie strona odbierająca ustawia HEAD na ostateczną odpowiedź.
JasonSmith

1
@ctn To po prostu dlatego, że zapomniałem opcji -f( --force). Odpowiednio zredagowałem odpowiedź. Następnie odpowiedź, o której mowa, używa tej samej opcji.
VonC

42

Aktualizacja: Działa to tylko w przypadku lokalnej kopii repozytorium („klient”). Zobacz komentarze innych poniżej.

W najnowszej wersji git (luty 2014) poprawna procedura wyglądałaby tak:

git remote set-head $REMOTE_NAME $BRANCH

Na przykład przełączenie głowicy ze zdalnego originna gałąź developwyglądałoby tak:

git remote set-head origin develop


Czy ta funkcja wymaga najnowszej wersji git na serwerze, czy wystarczy, jeśli komputer kliencki ma niedawno zainstalowany git?
Mikko Rantalainen

3
@Totor jest zwięzły, ale ma rację; ta odpowiedź powinna zostać odrzucona. Git ma tę nieco mylącą koncepcję „lokalnej, domyślnej gałęzi dla zdalnego”. Pozwala na wpisanie „origin” zamiast „origin / defaultbranch” i działa wyłącznie po stronie klienta . Długa historia na git-scm.com/docs/git-remote # set-head
MarcH

1
aby potwierdzić, o czym mówi @MarchH: run git checkout -b default; git push origin HEAD; git remote set-head origin default. Możesz wtedy sprawdzić lokalne zmiany za pomocą cat .git/refs/remotes/origin/HEAD(powinno być ref: refs/remotes/origin/default), a brak zmian zdalnych za pomocą git remote show origin(nadal będzie to, czym było przed dodaniem domyślnej gałęzi).
De Novo

37

Skoro wspominasz o GitHubie, aby zrobić to na ich stronie, po prostu wejdź do swojego projektu, a następnie ...

admin > Default Branch > (choose something)

Gotowe.


1
Doskonały! To był ostatni brakujący fragment.
berkus,

Moje źródło / HEAD wskazuje już gałąź funkcji zamiast wzorca. Próbowałem zmieniać "główną gałąź" w tę iz powrotem, ale nie wpłynęło to na HEAD ... Jakieś sugestie?
Daniil Shevelev

3
Ustawienia> Oddziały> Domyślny oddział
Chun Yang

12

Zobacz: http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html

To ustawia domyślną gałąź w repozytorium git. Możesz uruchomić to w czystych lub lustrzanych repozytoriach.

Stosowanie:

$ git symbolic-ref HEAD refs/heads/<branch name>

6
$ git symbolic-ref HEAD refs / heads / name-of-branch
Lamy

Zrobiłem to w moim zdalnym repozytorium i naprawiłem moje problemy z klonowaniem, gdzie z jakiegoś powodu głowa była nazwą innej gałęzi i dlatego próba sklonowania wzorca skutkowałaby błędem podczas próby zamknięcia mastera w edytorze, może to być bardzo specyficzne dla tego scenariusza , ale inni mogą być w takiej sytuacji i zastanawiać się, co robić
Christopher Thomas

10

(Istniało już w zasadzie to samo pytanie „ utwórz symboliczny odnośnik git w zdalnym repozytorium ”, na które nie było uniwersalnej odpowiedzi).

Ale są konkretne odpowiedzi dla różnych „farm” git (gdzie wielu użytkowników może zarządzać repozytoriami git przez ograniczony interfejs: przez http i ssh): http://Github.com , http://Gitorious.org , http: / /repo.or.cz , Girar ( http://git.altlinux.org ).

Te konkretne odpowiedzi mogą być przydatne dla osób czytających tę stronę i myślących o tych konkretnych usługach.


4
Teraz mają rozwijane menu do wyboru gałęzi HEAD na repo.or.cz (przykład: repo.or.cz/editproj.cgi?name=for-me-and-for-all_imz.git ) i gitorious.org , też. Wspaniały!
imz - Ivan Zakharyaschev

7

Jeśli masz dostęp do zdalnego repozytorium z powłoki, po prostu przejdź do .git (lub głównego katalogu, jeśli jest to nagie repozytorium) i zmień plik HEAD, aby wskazywał na właściwą głowę. Na przykład, domyślnie zawsze zawiera „refs: refs / heads / master”, ale jeśli chcesz zamiast tego foo być HEAD, po prostu edytuj plik HEAD i zmień zawartość na „refs: refs / heads / foo”.


Mam uprawnienia administratora na serwerze Git i zrobiłem dokładnie to samo. Używamy Gitolite i poszedłem do repozytorium, które stworzyłem. Nazwa katalogu to myrepo.git. Zawartość pliku HEAD w podanym katalogu została zmieniona z ref: refs/heads/masterna ref: refs/heads/mainline. Teraz, kiedy próbuję sklonować repozytorium na mojej lokalnej skrzynce, nadal wskazuje na master. Uruchomiłem git clone ssh://gitolite@git.server/myrepopolecenie. Jakiś pomysł na takie zachowanie?
Technext

Wersja serwera Git: git version 1.7.1& Wersja klienta Git:git version 1.9.4.msysgit.2
Technext

5

Możesz utworzyć odłączoną gałąź główną używając tylko porcelanowych poleceń Git:

git init
touch GO_AWAY
git add GO_AWAY
git commit -m "GO AWAY - this branch is detached from reality"

To daje nam główną gałąź z niegrzeczną wiadomością (możesz być bardziej uprzejmy). Teraz tworzymy naszą "prawdziwą" gałąź (nazwijmy ją pnia na cześć SVN) i oddzielamy ją od mistrza :

git checkout -b trunk
git rm GO_AWAY
git commit --amend --allow-empty -m "initial commit on detached trunk"

Cześć Presto! gitk - wszystkie pokażą master i trunk bez połączenia między nimi.

„Magia” polega na tym, że --amend powoduje, że git commit tworzy nowy commit z tym samym rodzicem, co obecny HEAD, a następnie wskazuje HEAD na to. Ale obecny HEAD nie ma rodzica, ponieważ jest to początkowe zatwierdzenie w repozytorium, więc nowy HEAD też go nie otrzymuje, co powoduje ich odłączenie od siebie.

Stare zatwierdzenie HEAD nie jest usuwane przez git-gc, ponieważ refs / heads / master wciąż na to wskazuje.

Flaga --allow-empty jest potrzebna tylko dlatego, że zatwierdzamy puste drzewo. Gdyby po git rm były jakieś dodatki git, nie byłoby to konieczne.

Prawdę mówiąc, możesz utworzyć odłączoną gałąź w dowolnym momencie, rozgałęziając początkowe zatwierdzenie w repozytorium, usuwając jego drzewo, dodając odłączone drzewo, a następnie wykonując git commit --amend .

Wiem, że to nie odpowiada na pytanie, jak zmodyfikować domyślną gałąź w zdalnym repozytorium, ale daje jasną odpowiedź, jak utworzyć odłączoną gałąź.


1
Możesz łatwiej utworzyć odłączoną gałąź, pobierając niepowiązaną gałąź z innego repozytorium i nadając jej nazwę. Na przykład git fetch git:user@example.com:foo remote-branch-name && git checkout -b detached-branch FETCH_HEADdoda nową gałąź, detached-branchktóra pasuje do gałęzi remote-branch-namew zdalnym git:user@example.com:foo. Oczywiście „zdalne” może być repozytorium w lokalnym systemie plików, które wcześniej przygotowałeś.
Mikko Rantalainen

2

Najpierw utwórz nową gałąź, którą chcesz ustawić jako domyślną, na przykład:

$>git branch main

Następnie wepchnij tę gałąź do początku :

$>git push origin main

Teraz, kiedy logujesz się na swoje konto GitHub, możesz przejść do swojego repozytorium i wybrać Ustawienia> Domyślna gałąź i wybrać „ główne ”.

Następnie, jeśli wybierzesz, możesz usunąć gałąź główną:

$>git push origin :master


Kluczową kwestią do zrozumienia jest to, że jeśli Twój dostawca hostingu (w tym przykładzie GitHub) nie zapewnia metody modyfikowania domyślnej gałęzi, nie masz szczęścia. Protokół Git nie zapewnia funkcji modyfikowania zdalnej gałęzi domyślnej; musiałbyś mieć możliwość uruchomienia git symbolic-refna zdalnej powłoce lub w inny sposób zmodyfikować plik tekstowy wywoływany HEADw katalogu głównym zdalnego repozytorium.
Mikko Rantalainen

2

W związku z pytaniem znalazłem się tutaj podczas wyszukiwania:

Jak powiadomić lokalne repozytorium o zmienionej domyślnej gałęzi w serwisie GitHub

Dla kompletności, dodając odpowiedź:

git remote set-head origin -a

0

Dla ludzi gitolite, gitolite obsługuje polecenie o nazwie - czekaj na to - symbolic-ref. Pozwala na zdalne uruchomienie tego polecenia, jeśli masz uprawnienia W (zapis) do repozytorium.


-1

Po prostu zaloguj się na swoje konto GitHub i po prawej stronie w menu nawigacyjnym wybierz Ustawienia , w zakładce Ustawienia wybierz Oddział domyślny i wróć do strony głównej repozytorium, które mi się udało.


1
Chociaż pokazuje nową gałąź jako domyślną w interfejsie GitHub, podczas wykonywania klonu git [repo], nie otrzymuję tej gałęzi. tzn. .git / HEAD zawiera nieprawidłowy ref.
Joseph Sheedy,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.