Rozgałęzienie Git: master vs. origin / master vs. pilates / origin / master

201

Myślę, że jestem na dobrej drodze, aby zrozumieć podstawowe pojęcia git.

Już skonfigurowałem i sklonowałem zdalne repozytorium. Utworzyłem również puste repozytorium po stronie serwera i połączyłem z nim moje lokalne repozytorium.

Mój problem polega na tym, że nie rozumiem różnicy między:

  • origin / master vs. piloty / origin / master

O ile rozumiem, master jest gałęzią lokalną, a piloty / origin / master są zdalne.

Ale czym dokładnie jest pochodzenie / mistrz ?

John Rumpel
źródło
1
@ChristopherWallace: W swojej edycji sprowokowałeś dwa pytania dotyczące meta: „ Czy naprawdę potrzebujemy tagu [origin]? ” I „ Jaki jest prawdziwy [Master]? ”.
Deduplicator
@Deduplicator Czy to problem?
nbro
@ChristopherWallace: Cóż, wielu uważa, że ​​oba tagi (ten, który stworzyłeś i ten, który właśnie dodałeś) są złe. Zdarza mi się zgadzać, ale być może masz coś do dodania do powiązanej dyskusji, co nie zostało wzięte pod uwagę. Jeśli nie, wydaje się, że tak.
Deduplicator
Dalsze pytanie: po co .git/refs/origin/masterkiedykolwiek dryfować .git/refs/remotes/origin/master? To się teraz dzieje i jestem wyrzucany.
Paul

Odpowiedzi:

219

Weź klon zdalnego repozytorium i uruchom git branch -a(aby pokazać wszystkie gałęzie, o których git wie). Prawdopodobnie będzie wyglądać mniej więcej tak:

* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Tutaj masterjest gałąź w lokalnym repozytorium. remotes/origin/masterto gałąź nazwana masterna pilocie o nazwie origin. Możesz to nazwać albo origin/master, jak w:

git diff origin/master..master

Możesz również nazywać to remotes/origin/master:

git diff remotes/origin/master..master

To tylko dwa różne sposoby odwoływania się do tej samej rzeczy (nawiasem mówiąc, oba te polecenia oznaczają „pokaż mi zmiany między mastergałęzią zdalną a moją mastergałęzią).

remotes/origin/HEADjest default branchdla pilota o nazwie origin. To pozwala po prostu powiedzieć originzamiast origin/master.

Larsks
źródło
5
Dobra odpowiedź. Myślę, że git branch -apokazanie zdalnej gałęzi remotes/origin/masterjest częściowo spowodowane tym, że bazowy ref jest przechowywany w .git/refs/remotes/origin(jeśli nie został spakowany). Moim zdaniem wyjście git branch -amoże być znacznie wyraźniejsze, być może poprzez oddzielenie nazwy pilota od nazwy gałęzi czymś innym niż ukośnik.
Matt Hurne
14
Zauważ też, że git branch -rtylko pokazywanie gałęzi zdalnych spowoduje wyświetlenie gałęzi tylko origin/masterdlatego, że remotes/prefiks nie jest konieczny.
Matt Hurne
3
@misterbiscuit: to prawda. Wyniki są bardziej mylące niż wyjaśnianie. Wielkie dzięki, świetna odpowiedź na moje pytanie, która dała mi właściwe wskazówki
John Rumpel
Jeśli patrzę na git logwidzę commit fa9sd8jasdf98 (HEAD -> master), co to znaczy? Co to jest HEAD w tym przypadku? Myślałem, że jestem obecnie „mistrzem” i zobowiązuję się origin/master. Myślę, że coś pomieszałem, czy ktoś mógłby pomóc się uspokoić? EDYCJA AKTUALIZACJI: Wydaje mi się, że rozumiem, czy poprawne jest założenie, że HEAD wskazuje obecnie na gałąź master, co oznacza, że ​​obecnie jestem w trakcie procesu master?
Sebastian Nielsen
@SebastianNielsen tak masz rację, HEAD -> część master oznacza, że ​​jesteś obecnie w gałęzi master.
iRestMyCaseYourHonor
108

Krótka odpowiedź dla manekinów takich jak ja (skradzionych z Torek):

  • origin / master to „gdzie master był tam ostatnim razem, gdy sprawdzałem”
  • master to „gdzie master jest tutaj na podstawie tego, co robiłem”
ErichBSchulz
źródło
9
origin / master = kopia zapasowa zdalnego komputera, zaktualizowana przy ostatnim sprawdzaniu master = twoja kopia origin / master
sakurashinken
40

Technicznie nie ma właściwie żadnych „remote” rzeczy w ogóle 1 w swoim repo Git, istnieją tylko lokalne nazwy, które powinny odpowiadać nazwom na innym, różnym repo. Te, które wymieniono, origin/whateverbędą początkowo pasować do tych z repozytorium, które sklonowałeś:

git clone ssh://some.where.out.there/some/path/to/repo # or git://some.where...

tworzy lokalną kopię drugiego repozytorium. Po drodze odnotowuje wszystkie gałęzie, które tam były, i zatwierdza te, do których się odwołuje, i umieszcza je w lokalnych repozytoriach pod nazwami refs/remotes/origin/.

W zależności git fetchod tego, ile czasu upływa przed Tobą lub ekwiwalent, aby zaktualizować „moją kopię tego, co jest gdzieś.out.out.there”, mogą zmieniać swoje gałęzie, tworzyć nowe i usuwać niektóre. Kiedy zrobisz swoje git fetch(lub git pullktóre jest naprawdę pobranie i scalenie), twoje repozytorium wykona kopie ich nowej pracy i zmieni wszystkie refs/remotes/origin/<name>wpisy w razie potrzeby. To ten moment fetching sprawia, że ​​wszystko się zgadza (no cóż, to i początkowy klon, a także niektóre przypadki pushing - w zasadzie za każdym razem, gdy Git ma szansę sprawdzić - ale patrz zastrzeżenie poniżej).

Git zwykle mówi, że używasz własnego refs/heads/<name>jako sprawiedliwego <name>, a tych zdalnych jako origin/<name>i wszystko działa, ponieważ jest oczywiste, który z nich jest który. Czasami możliwe jest utworzenie własnych nazw oddziałów, które sprawiają, że nie jest to oczywiste, ale nie martw się tym, dopóki to się nie stanie. :-) Wystarczy podać Git najkrótszą nazwę, która będzie oczywista, i zacznie się od tego: origin/masterjest „gdzie mistrz był tam, kiedy ostatnio sprawdzałem”, i masterjest „gdzie mistrz jest tutaj, na podstawie tego, co robiłem” . Uruchom, git fetchaby w razie potrzeby zaktualizować Gita „gdzie jest master”.


Uwaga: w wersjach Gita starszych niż 1.8.4, git fetchma kilka trybów, które nie aktualizują się „tam, gdzie jest master” (a dokładniej tryby, które nie aktualizują żadnych gałęzi zdalnego śledzenia). Uruchomiony git fetch origin, lub git fetch --all, lub nawet po prostu git fetch, robi aktualizację. Bieganie git fetch origin master nie . Niestety ten tryb „nie aktualizuje się” jest uruchamiany przez zwykły git pull. (Jest to głównie niewielka irytacja i zostało naprawione w Git 1.8.4 i nowszych).


1 Cóż, jedna rzecz nazywa się „zdalną”. Ale to także lokalne! Nazywa się originto, co Git nazywa „zdalnym”. Jest to po prostu krótka nazwa adresu URL użytego podczas klonowania. Jest to także wtedy, gdy originw origin/masterpochodzi. Nazwa origin/masternazywa się gałęzią zdalnego śledzenia , która czasami zostaje skrócona do „gałęzi zdalnej”, szczególnie w starszej lub bardziej nieformalnej dokumentacji.

Trek
źródło
2
Doskonały opis dla nowicjusza takiego jak ja, dziękuję! Wyjaśniono, dlaczego nakleiła origin/masternaklejkę na localwykresie repozytorium, a nie na remotejednym (szczerze polecam prezentację Jessiki Kerra „Git Happens” dla osób, które dopiero zaczynajągit : vimeo.com/46010208 . głowie między 30:00 - 30: 19.)
starszy starszy
11

Spróbuję uprościć odpowiedź @ ErichBSchulz dla początkujących:

  • origin / master to stan gałęzi master w zdalnym repozytorium
  • master to stan oddziału master w lokalnym repozytorium
MKJ
źródło
1
dobra próba, ale IMHO w / out last time I've checkedtraci ważną kwestię
Aleksiej Martianow
6
  1. origin - Jest to niestandardowa i najczęstsza nazwa wskazująca na zdalne.

$ git remote add origin https://github.com/git/git.git--- Uruchomisz to polecenie, aby połączyć swój projekt github z początkiem. Tutaj pochodzenie jest zdefiniowane przez użytkownika. Możesz zmienić nazwę przez$ git remote rename old-name new-name


  1. master - Domyślna nazwa oddziału w Git to master. Zarówno dla komputera zdalnego, jak i lokalnego.

  1. origin / master - Jest to tylko wskaźnik odsyłający do gałęzi master w zdalnym repo. Pamiętaj, że powiedziałem, że origin wskazuje na pilota.

$ git fetch origin- Pobiera obiekty i referencje ze zdalnego repozytorium na komputer lokalny [origin / master]. Oznacza to, że nie wpłynie to na lokalny oddział główny, chyba że połączysz je za pomocą$ git merge origin/master . Pamiętaj, aby sprawdzić poprawną gałąź, w której musisz scalić przed uruchomieniem tego polecenia

Uwaga: Pobrana zawartość jest reprezentowana jako gałąź zdalna. Fetch daje Ci możliwość przejrzenia zmian przed zintegrowaniem ich z kopią projektu. Aby pokazać zmiany między twoim a zdalnym$git diff master..origin/master

Gnanasekar S.
źródło
5

Jedno wyjaśnienie (i kwestia, która mnie pomyliła):

„piloty / pochodzenie / HEAD jest domyślną gałęzią” nie jest tak naprawdę poprawne.

pilot / origin / master był domyślną gałęzią w zdalnym repozytorium (ostatnim razem, gdy sprawdzałeś). HEAD nie jest gałęzią, tylko wskazuje na gałąź.

Pomyśl o HEAD jako o swoim miejscu pracy. Kiedy myślisz o tym w ten sposób, wówczas „git checkout branchname” ma sens w odniesieniu do zmiany plików obszaru roboczego na pliki określonej gałęzi. Pliki oddziałów „kasujesz” do swojego obszaru roboczego. GŁOWICA do wszystkich praktycznych celów jest widoczna dla Ciebie w miejscu pracy.

stóg
źródło
Dokładniej, HEADjest „wskaźnikiem do gałęzi” (rzeczywisty plik w lokalnym repozytorium często zawiera ciąg znakówref: refs/heads/master , na przykład ... chyba że jest „odłączony”, co jest zupełnie inną rzeczą). Jednak istnieje pewien rodzaj błędu w sposobie cloneinterpretacji „zdalnej HEAD”: protokoły przesyłania nie mogą w ogóle wysłać pośredniej gałęzi, tylko surowy SHA-1, więc git ma kludge, który sprawia, że ​​„działa głównie”. Jednak od czasu do czasu ktoś napotyka dziwną sprawę. Chciałbym, żeby git w ogóle nie stworzył remotes/origin/HEAD, zwłaszcza gdy wyjdzie źle ...
trek
2

Myślę, że ten zapis git slash najlepiej jest zrozumieć, zaglądając do twojego .gitfolderu.


Na przykład, tutaj jest nieco skrócone drzewo mojego .git dla bazy źródłowej LibreOffice.

W Linuksie sudo apt-get install tree warto to zobaczyć.
W systemie Windows myślę, że treepolecenie może nadal działać.

Przewiń w dół i spójrz na referencje (aka „referencje”) u dołu:

$ tree  
.  
├── branches  
├── config  
├── description  
├── FETCH_HEAD  
├── gitk.cache  
├── HEAD  
├── hooks  
│   ├── applypatch-msg.sample  
    ...
├── index  
├── info  
│   └── exclude  
├── logs  
│   ├── HEAD  
│   └── refs  
│       ├── heads  
│       │   ├── master  
│       │   └── remotes  
│       │       └── origin  
│       └── remotes  
│           └── origin  
│               ├── distro  
│               │   ├── cib  
│               │   │   └── libreoffice-6-0  
│               │   ├── collabora  
│               │   │   └── cp-6.0  
│               │   └── lhm  
│               │       └── libreoffice-5-2+backports  
│               ├── HEAD  
│               ├── libreoffice-6-2  
│               ├── master  
│               └── private  
│                   └── mst  
│                       └── sw_redlinehide_4a  
├── objects  
│   ├── info  
│   └── pack  
│       ├── pack-b80087dc57e2b3315f449ca0f1aaa91987bf0c5e.idx  
│       ├── pack-b80087dc57e2b3315f449ca0f1aaa91987bf0c5e.pack  
│       ├── pack-eb4e6808029e712d8d9c2671accbbd98aaeb9a04.idx  
│       └── pack-eb4e6808029e712d8d9c2671accbbd98aaeb9a04.pack  
├── ORIG_HEAD  
├── packed-refs  
└── refs  
    ├── heads  
    │   ├── master  
    │   └── remotes  
    │       └── origin  
    ├── remotes  
    │   └── origin  
    │       ├── distro  
    │       │   ├── cib  
    │       │   │   └── libreoffice-6-0  
    │       │   ├── collabora  
    │       │   │   └── cp-6.0  
    │       │   └── lhm  
    │       │       └── libreoffice-5-2+backports  
    │       ├── HEAD  
    │       ├── libreoffice-6-2  
    │       ├── master  
    │       └── private  
    │           └── mst  
    │               └── sw_redlinehide_4a  
    └── tags  
        └── libreoffice-6-2-branch-point  

32 directories, 45 files

Mogłoby być mniej mylące, gdyby było tak ułożone, ale nie było:

repositories (i.e. independent trees)
├──local
│  └──master
│
└──origin1
│  └──master
└──origin2
   └──master

Mamy trzy podstawowe typy referencji: głowice , piloty i tagi .

  • .git / refs / heads posiada naszego lokalnego mistrza .

  • .git / referencje / piloty mogą zawierać wiele pilotów, chociaż w tej chwili mamy tylko ich źródło .

  • .git / refs / tags (omówiono gdzie indziej).

pochodzenie zatem naszym jedynym i jedynym odległym. Przechowuje pochodzenie / master .


Okazuje się, że mamy 2 GŁOWICE (wskaźniki do bieżących gałęzi), jeden lokalny i jeden zdalny:

$ cat .git/HEAD                        #         local:  HEAD -> master
ref: refs/heads/master

$ cat .git/refs/remotes/origin/HEAD    # remote origin:  HEAD -> master
ref: refs/remotes/origin/master

Jeśli wymienisz swoje oddziały :

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/aoo/aw080
  remotes/origin/aoo/trunk
  remotes/origin/distro/capgemini/cg-4.1
  remotes/origin/distro/cib/libreoffice-5-0
  remotes/origin/distro/cib/libreoffice-5-1
  remotes/origin/distro/cib/libreoffice-5-2
  ...
  • Pierwsza wymieniona gałąź ( master ) jest jedyną, która nie jest zdalna. W tym przypadku mamy jeden oddział lokalny. Od tego zaczniemy naszą własną pracę, dla naszych nowych oddziałów i kolejnych zobowiązań.

Następnie możesz mieć wiele oddziałów zdalnego śledzenia, a my robimy to tutaj. Wiesz, że są to oddziały zdalnego śledzenia, ponieważ są one poprzedzone znakiem „ piloty / ”. Te pokazane tutaj dotyczą zdalnego nazwanego źródła.

  • Tak więc druga linia jest bieżącym wskaźnikiem gałęzi pochodzenia . Piloty / pochodzenie: HEAD - wskazuje na -> master. To pokazuje, że w zdalnym repozytorium bieżąca gałąź jest ich gałęzią o nazwie master (nie mylić z naszą lokalną gałąź o nazwie master ).

  • Pozostałe gałęzie nie znajdują się w twoim .git / refs / tree, ale raczej je znajdziesz .git/packed-refs .

Kiedy my pobierania pobieramy zmiany ze zdalnego repozytorium do naszego zdalnego repozytorium śledzącego.

Kiedy my się, łączymy zmiany w tym lokalnym, zdalnym repozytorium śledzenia z działającym oddziałem lokalnym lub oddziałami, w tym przypadku z naszym oddziałem głównym.

(Kiedy my ciągnąć , wykonujemy oba te dwa kroki w jednej operacji.)


Warto również zauważyć, że te lokalne i zdalne UUID dla mastera wskazują obecnie ten sam węzeł (inaczej „zatwierdzenie”):

$ cat refs/heads/master                   # local         master
1ca409292272632f443733450313de5a82c54a9c

$ cat refs/remotes/origin/master          # remote origin master
1ca409292272632f443733450313de5a82c54a9c

Nasz lokalny master wskazuje więc to samo miejsce, co master origin pilota:

[local] master = [remote] origin master

Wreszcie, myślę, że warto też na to spojrzeć .git/packed-refs

$ cat packed-refs 
# pack-refs with: peeled fully-peeled 
3c1d4742e649fe9c8aed8c2817fe3e1f3364f298 refs/remotes/origin/aoo/aw080
e87c8b7922e9a73e0abb7f9a7a47c9ac3374a826 refs/remotes/origin/aoo/trunk
b70fdffb041c12f124dcc0822b61bf3450e53137 refs/remotes/origin/distro/capgemini/cg-4.1
5dbc3f1754809b9489faaf380b1a4bdbcfbb6205 refs/remotes/origin/distro/cib/libreoffice-5-0
cfdbc96ca47d68d6785fd21829a8d61f49d6e591 refs/remotes/origin/distro/cib/libreoffice-5-1
5189c8c47461ef09739086e55512fc6a10245273 refs/remotes/origin/distro/cib/libreoffice-5-2
3bee5917569ca8e6ee3b086458f5b1a917b88ca1 refs/remotes/origin/distro/cib/libreoffice-5-3
92fbe703f9ca480d3a2b8610d87e991c729edf77 refs/remotes/origin/distro/cib/libreoffice-5-4
05c0a5df66cc69d75280f05b804cf82f3387d42b refs/remotes/origin/distro/cib/libreoffice-6-0
7fe193e759b24b90852e6e327115b77114d7b119 refs/remotes/origin/distro/cib/libreoffice-6-1
8187f7aa413e7ef7b377eea2b057d336bf256867 refs/remotes/origin/distro/collabora/cd-5.3
7a6b608591e21ef61dc05cff9fc58da531035755 refs/remotes/origin/distro/collabora/cd-5.3-3.1
....

Bez wątpienia pozostawia to więcej pytań niż odpowiedzi, ale myślę, że może pomóc Ci odpowiedzieć na własne pytania dotyczące tego, co jest.

Widok eliptyczny
źródło