Czym różni się tag od oddziału w Git? Którego powinienem użyć tutaj?

615

Mam pewne trudności ze zrozumieniem, jak używać znaczników w porównaniu z oddziałami w.

Właśnie przeniosłem bieżącą wersję naszego kodu do , a teraz będę pracował nad podzbiorem tego kodu dla określonej funkcji. Pracuje nad tym także kilku innych programistów, ale nie wszyscy programiści z naszej grupy będą dbać o tę funkcję. Czy powinienem tworzyć gałąź czy tag? W jakich sytuacjach powinienem używać jednego kontra drugiego?

Białecki
źródło
4
Ponieważ poszukiwanie w Internecie sposobu używania tagu git doprowadziło mnie najpierw do tego linku, dodaję, że tutaj jest lepsza odpowiedź (IMHO) na temat tagu: stackoverflow.com/questions/35979642/...
Alexei Martianov

Odpowiedzi:

519

Tag reprezentuje wersję danego oddziału na chwilę w czasie. Gałąź stanowi oddzielną nić rozwoju, które mogą być realizowane równolegle z innymi działaniami rozwoju na podstawie tego samego kodu. Zmiany w oddziale można ostatecznie scalić z powrotem w innym oddziale, aby je ujednolicić.

Zazwyczaj będziesz oznaczyć konkretnej wersji, dzięki czemu można go odtworzyć, na przykład, jest to wersja wysyłaliśmy do XYZ Corp . oddział to bardziej strategia zapewniania bieżących aktualizacji konkretnej wersji kodu przy jednoczesnym rozwijaniu go. Zrobisz gałąź dostarczonej wersji, będziesz kontynuować programowanie w linii głównej, ale poprawisz błędy w gałęzi, która reprezentuje dostarczoną wersję. Ostatecznie poprawisz te poprawki błędów z powrotem do głównej linii. Często będziesz używać jednocześnie rozgałęziania i tagowania. Będziesz mieć różne tagi, które mogą odnosić się zarówno do linii głównej, jak i jej gałęzi, oznaczając poszczególne wersje (na przykład dostarczone klientom) wzdłuż każdej gałęzi, którą chcesz odtworzyć - do dostawy, diagnozy błędów itp.

W rzeczywistości jest to bardziej skomplikowane - lub tak skomplikowane, jak chcesz - ale te przykłady powinny dać ci pojęcie o różnicach.

tvanfosson
źródło
40
w jego przypadku chce używać rozgałęzień, może też powinieneś to zauważyć w swojej odpowiedzi;)
knittl
13
AFAIK, tagi nie są unikalne dla poszczególnych gałęzi. Więc nie możesz podać tych samych nazw dla różnych zatwierdzeń w oddzielnych gałęziach.
MÓJ
5
@MY Na pewno nie jest to zła rzecz, IMHO. Zwłaszcza w sposób opisany przez tvanfosson posiadanie więcej niż jednego znacznika o tej samej nazwie w różnych gałęziach może być trudne do utrzymania. Biorąc pod uwagę ten przykład, sądzę, że gdybyś mógł mieć tagi o tej samej nazwie w różnych gałęziach, szybko byłoby to uznane za złą praktykę. Dobrze wiedzieć, że nie możesz. Dzięki MÓJ!
Obrót
28
Tag to tylko alias skrótu zatwierdzenia. Tak samo, jak możesz kasować zatwierdzenie za pomocą git checkout 88c9f229f, możesz zrobić coś podobnego git checkout your_tagi kasujesz zatwierdzenie, które zostało aliowane przez tag.
jterm
6
@jterm, czy aliasy gałęzi też nie są? Jedyna różnica polega na tym, że alias gałęzi automatycznie powraca do ostatniego zatwierdzenia w łańcuchu.
Viktor Molokostov
529

Z teoretycznego punktu widzenia:

  • tagi są symbolicznymi nazwami dla danej wersji . Zawsze wskazują na ten sam obiekt (zwykle: na tę samą wersję); nie zmieniają się.
  • gałęzie są symbolicznymi nazwami linii rozwoju . Nowe zatwierdzenia są tworzone na górze oddziału. Wskaźnik gałęzi naturalnie przesuwa się, wskazując na coraz nowsze zatwierdzenia.

Z technicznego punktu widzenia:

  • tagi znajdują się w refs/tags/przestrzeni nazw i mogą wskazywać na tagi obiektów ( tagi z adnotacjami i opcjonalnie podpisane GPG) lub bezpośrednio w celu zatwierdzenia obiektu (rzadziej używany lekki tag dla nazw lokalnych), lub w bardzo rzadkich przypadkach nawet na obiekt drzewa lub obiekt blob (np. podpis GPG ).
  • gałęzie znajdują się w refs/heads/przestrzeni nazw i mogą wskazywać tylko na zatwierdzanie obiektów . HEADWskaźnik musi odnosić się do gałęzi (symboliczne odniesienia) lub bezpośrednio do zatwierdzenie (jednej strony głowy lub Nienazwana rozgałęzienia).
  • gałęzie zdalnego śledzenia znajdują się w refs/remotes/<remote>/przestrzeni nazw i podążają za zwykłymi gałęziami w zdalnym repozytorium <remote>.

Zobacz także stronę gitglossary :

Oddział

„Gałąź” to aktywna linia rozwoju. Najnowsze zatwierdzenie w gałęzi jest określane jako końcówka tej gałęzi. Na czubku gałęzi znajduje się głowa gałęzi, która porusza się do przodu, gdy gałąź jest rozwijana w sposób dodatkowy. Pojedyncze repozytorium git może śledzić dowolną liczbę gałęzi, ale twoje drzewo robocze jest powiązane tylko z jedną z nich (gałąź „bieżąca” lub „wyewidencjonowana”), a HEAD wskazuje na tę gałąź.

etykietka

Ref wskazujący na znacznik lub obiekt zatwierdzenia. W przeciwieństwie do head tag nie jest zmieniany przez zatwierdzenie. Znaczniki (nie obiekty znaczników) są przechowywane w $GIT_DIR/refs/tags/. [...] Znacznik jest najczęściej używany do oznaczenia określonego punktu w łańcuchu przodków zatwierdzenia.

obiekt znacznika

Obiekt zawierający odwołanie wskazujące na inny obiekt, który może zawierać komunikat podobnie jak obiekt zatwierdzenia. Może także zawierać podpis (PGP), w którym to przypadku nazywany jest „podpisanym obiektem znacznika”.

Jakub Narębski
źródło
36
Pytanie: jeśli traktujesz gałąź jak znacznik (to znaczy, że tworzysz ją, a potem nigdy jej nie aktualizujesz), czy jest jakaś różnica?
Steve Bennett
30
@SteveBennett absolutnie. Zawiera różne informacje (możesz podpisać tag, możesz dodać opis do oddziału). Możesz przenieść gałąź (więc nawet jeśli nigdy jej nie zaktualizujesz, nadal możesz ją zmienić). Nie możesz przenieść tagu (jest on powiązany z konkretnym zatwierdzeniem). Możesz wybrać wypchnięcie gałęzi. Tagi nie są domyślnie wypychane. Nigdy nie powinieneś używać jednego do drugiego (chyba, że ​​naprawdę jesteś nastawiony na SVN, w którym to przypadku musisz „oduczyć się” tak szybko, jeśli chcesz kontynuować z git).
VCC
19
@ SteveBennett: Istnieje różnica w tym, jak Git traktuje gałęzie, a jak traktuje tagi. Poza tym, co powiedział VonC, nie można przez pomyłkę przesuwać znacznika: „ git checkout <tag>” wygenerowałby anonimową gałąź bez nazwy (tak zwaną „odłączoną HEAD”) i wybrałby stan znacznika. Utworzenie nowego zatwierdzenia robi to w tej nienazwanej gałęzi i nie zmienia tego, na co wskazuje znacznik.
Jakub Narębski
60
IMO, gałęzie są oddzielnymi osiami czasu (świat równoległy), a znaczniki to określone momenty na osi czasu.
Eonil
25
Nikt tutaj jeszcze o tym nie wspomniał, ale możesz użyć tagu jako punktu do założenia oddziału:git checkout -b <branch name> <tag name>
143

Jeśli myślisz o swoim repozytorium jako książce, która kronika postępów w projekcie ...

Gałęzie

Możesz myśleć o oddziale jako o jednej z lepkich zakładek :

wprowadź opis zdjęcia tutaj

Zupełnie nowe repozytorium ma tylko jedno (wywoływane master), które automatycznie przechodzi do najnowszej strony (pomyśl o zatwierdzeniu ), którą napisałeś. Możesz jednak tworzyć i używać więcej zakładek, aby oznaczyć inne interesujące miejsca w książce, abyś mógł szybko do nich wrócić.

Ponadto zawsze możesz przenieść określoną zakładkę na inną stronę książki ( git-resetna przykład używając ); Punkty zainteresowania zwykle różnią się w czasie.

Tagi

Możesz myśleć o znacznikach jako o nagłówkach rozdziałów .

zakładki

Może zawierać tytuł (pomyśl tagi z adnotacjami ) lub nie. Znacznik jest podobny, ale różni się od gałęzi, ponieważ stanowi punkt historycznego zainteresowania książką. Aby zachować jego historyczny aspekt, po udostępnieniu tagu (tj. Przekazaniu go do udostępnionego pilota) nie należy przenosić go w inne miejsce w książce.

jub0bs
źródło
16
Wyobrażam sobie, że gałąź to książka, a zakładki to tagi. Możesz kontynuować pisanie książki, ale nie możesz jej edytować. Tag to tylko ustalony moment w książce.
Mārtiņš Briedis
5
@Jubobs Podobało mi się wyjaśnienie gałęzi jako linia rozwoju. Książka byłaby gałęzią. Możesz rozpocząć nową książkę w oparciu o miejsce, w którym opuściłeś główną gałąź. Możesz napisać je równolegle, a następnie spróbować połączyć się w jedną książkę / gałąź.
Mārtiņš Briedis
2
@ MārtiņšBriedis Rozumiem sposób, w jaki lubisz myśleć o oddziale, ale uważam, że w Git jest to mylące. Zobacz stackoverflow.com/questions/25068543/…
jub0bs
2
ta odpowiedź naprawdę oszczędza czas
Ali Foroughi
2
Jeśli zaczniesz pisać książkę i masz pierwsze 50 stron, możesz ją skopiować (utworzyć z niej nowy oddział) i kontynuować pisanie dwóch książek jednocześnie (lub przekazać kopię książki innemu pisarzowi - twórcy), a na koniec możesz połączyć zmiany z innej książki na twoją.
barell
42

To, co musisz zrozumieć, pochodzące z CVS, to to, że nie tworzysz już katalogów podczas zakładania oddziału.
Koniec z „lepkim znacznikiem” (który można zastosować tylko do jednego pliku) lub „znacznikiem gałęzi”.
Rozgałęzienia i znaczniki są dwoma różnymi obiektami w Git i zawsze dotyczą wszystkich repozytoriów.

Nie będziesz już (tym razem z SVN) jawnie strukturyzować swoje repozytorium za pomocą:

branches
   myFirstBranch
     myProject
       mySubDirs
   mySecondBranch
     ...
tags
   myFirstTag
     myProject
       mySubDirs
   mySecondTag
   ...

Struktura ta wynika z faktu, że CVS jest systemem wersji, a nie systemem wersji (patrz Kontrola źródła vs. Kontrola wersji? ).
Oznacza to, że gałęzie są emulowane przez tagi dla CVS, kopie katalogów dla SVN.

Twoje pytanie ma sens, jeśli jesteś przyzwyczajony do kasy tagu i rozpocznij w nim pracę .
Czego nie powinieneś;)
Tag ma reprezentować niezmienną treść, służy tylko do uzyskania dostępu do niego z gwarancją uzyskania tej samej treści za każdym razem.

W Git historia zmian jest serią zatwierdzeń, tworzących wykres.
Gałąź to jedna ścieżka tego wykresu

x--x--x--x--x # one branch
    \ 
     --y----y # another branch
       1.1
        ^
        |
        # a tag pointing to a commit
  • Jeśli kasujesz tag, musisz utworzyć gałąź, aby zacząć z niego pracować.
  • Jeśli kasujesz oddział, zobaczysz bezpośrednio ostatnie zatwierdzenie („HEAD”) tego oddziału.

Widzieć Jakuba Narębskiego na wszystkie szczegóły techniczne, ale szczerze mówiąc, w tym momencie nie potrzebujesz (jeszcze) wszystkich szczegółów;)

Najważniejsze jest to, że znacznik jest prostym wskaźnikiem do zatwierdzenia, nigdy nie będziesz mógł modyfikować jego zawartości. Potrzebujesz oddziału.


W twoim przypadku każdy programista pracuje nad określoną funkcją:

  • powinni utworzyć własny oddział w swoim repozytorium
  • śledź oddziały z repozytoriów ich współpracowników (tego, który pracuje nad tą samą funkcją)
  • ciągnięcie / pchanie, aby dzielić się swoją pracą z rówieśnikami.

Zamiast bezpośrednio śledzić oddziały współpracowników, możesz śledzić tylko oddział jednego „oficjalnego” centralnego repozytorium, do którego wszyscy pchają swoją pracę w celu zintegrowania i udostępnienia pracy wszystkich dla tej konkretnej funkcji.

VonC
źródło
1
dziękuję za wyjaśnienie, w jaki sposób działają gałęzie i tagi :) nie byłbym w stanie zrozumieć tego bez twojego przykładu.
ufk
3
@VonC: Myślę, że masz na myśli „SVN” w swojej odpowiedzi, a nie „CVS”. CVS nie ma struktury katalogów; SVN robi. W rzeczywistości tagowanie w git bardziej przypomina mi tagowanie w RCS / CVS niż tagowanie w SVN (gdzie tag == zdegenerowana gałąź).
Chris Cleeland,
1
@ChrisCleeland dobry punkt. Próbowałem oddzielić nieco więcej punktów CVS i SVN w (zredagowanej) odpowiedzi.
VCC
37

Gałęzie są wykonane z drewna i wyrastają z pnia drzewa. Tagi są wykonane z papieru (pochodna drewna) i wiszą jak ozdoby świąteczne z różnych miejsc na drzewie.

Twój projekt jest drzewem, a twoja funkcja, która zostanie dodana do projektu, wzrośnie na gałęzi. Odpowiedź brzmi: oddział.

Jason
źródło
3
miłość do analogii
doz87
16

Wygląda na to, że najlepszym sposobem na wyjaśnienie jest to, że tagi działają jak gałęzie tylko do odczytu. Możesz użyć gałęzi jako tagu, ale możesz przypadkowo zaktualizować ją o nowe zatwierdzenia. Tagi gwarantują, że wskazują na to samo zatwierdzenie, o ile istnieją.

Wasilij Gorszkow
źródło
11
Tagi gwarantują, że wskazują na to samo zatwierdzenie, o ile istnieją. Nie do końca prawda. Możesz przenieść znacznik za pomocą git tag -f.
jub0bs
14

Tagi mogą być podpisane lub niepodpisane ; oddziały nigdy nie są podpisane.

Podpisane znaczniki nigdy nie mogą się przenosić, ponieważ są kryptograficznie powiązane (z podpisem) z określonym zatwierdzeniem. Nieoznaczone znaczniki nie są powiązane i można je przenosić (ale przenoszenie znaczników nie jest normalnym przypadkiem użycia).

Oddziały mogą nie tylko przejść do innego zatwierdzenia, ale oczekuje się, że to zrobią. Powinieneś użyć oddziału do swojego lokalnego projektu rozwoju. Nie ma sensu powierzanie pracy repozytorium Git „na znaczniku”.

Greg Hewgill
źródło
12

Lubię myśleć o oddziałach jak , gdzie idziesz , tagi jak gdzie byłaś .

Znacznik wydaje się jak zakładka do określonego ważnego punktu w przeszłości, takiego jak wydanie wersji.

Podczas gdy gałąź jest szczególną ścieżką, projekt idzie w dół, a zatem znacznik gałęzi przesuwa się wraz z tobą. Po zakończeniu scalasz / usuwasz gałąź (tj. Znacznik). Oczywiście w tym momencie możesz wybrać tagowanie tego zatwierdzenia.

Gazzer
źródło
6

Znacznik służy do oznaczenia wersji, a dokładniej odnosi się do punktu w czasie na gałęzi. Gałąź jest zwykle używana do dodawania funkcji do projektu.

Liczba 45
źródło
4

prosty:

Oczekuje się, że tagi zawsze będą wskazywać tę samą wersję projektu, podczas gdy oczekuje się, że nagłówki będą się rozwijać w miarę rozwoju.

Podręcznik użytkownika Git

Bar Horing
źródło
4

prosta odpowiedź brzmi:

gałąź: bieżący wskaźnik gałęzi przesuwa się przy każdym zatwierdzeniu do repozytorium

ale

tag: zatwierdzenie, którego wskazuje znacznik, nie zmienia się, w rzeczywistości znacznik jest migawką tego zatwierdzenia.

jsina
źródło