amikor a távoli git taget ellenőrzöm, ilyen parancsot használok:
git checkout -b local_branch_name origin/remote_tag_name
A következő hibát kaptam:
error: pathspec `origin/remote_tag_name` did not match any file(s) known to git.
Megtalálom a remote_tag_name-t, amikor a git tag parancsot használom.
A tag egy adott commit megjelölésére és jelölésére szolgál az előzményekben.
Általában kiadási pontok (pl. v1.0 stb.) jelölésére használják.
Bár a címke hasonlónak tűnhet egy ághoz, a címke azonban nem változik.
Ez közvetlenül egy specifikus commitra mutat az előzményekben.
Nem leszel képes a címkék ellenőrzésére, ha nem lesz lokálisan az adattáradban, így először is, a címkéket a helyi adattáradba kell behoznod
.
Először győződj meg róla, hogy a címke létezik-e helyben, a következő módon
# --all will fetch all the remotes.
# --tags will fetch all tags as well
git fetch --all --tags --prune
Aztán ellenőrizze a címkét a
git checkout tags/<tag_name> -b <branch_name>
A origin
helyett használd a tags/
előtagot.
Ebben a mintában 2 címke van 1.0 & 1.1 verziójú, a következők bármelyikével ellenőrizheti őket:
git checkout A ...
git checkout version 1.0 ...
git checkout tags/version 1.0 ...
A fentiek mindegyike ugyanazt fogja csinálni, mivel a tag csak egy mutató az adott commitra.
3 eredet: https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png
# list all tags
git tag
# list all tags with given pattern ex: v-
git tag --list 'v-*'
A címkék létrehozásának 2 módja van:
# lightweight tag
git tag
# annotated tag
git tag -a
A különbség a 2 között az, hogy a megjegyzésekkel ellátott tag létrehozásakor ugyanúgy hozzáadhatsz metaadatokat, mint egy git commitban:
név, e-mail, dátum, megjegyzés & aláírás.
# delete any given tag
git tag -d <tag name>
# Don't forget to remove the deleted tag form the server with push tags
Egy adott tag tartalmának megragadásához használhatod a checkout
parancsot.
Ahogy fentebb már elmagyaráztuk, a címkék ugyanolyanok, mint bármely más commit, így használhatjuk a checkout
parancsot, és az SHA-1 helyett egyszerűen kicserélhetjük a tag_name-ra.
1. lehetőség:
# Update the local git repo with the latest tags from all remotes
git fetch --all
# checkout the specific tag
git checkout tags/<tag> -b <branch>
2. lehetőség:
Mivel a git támogatja a shallow clone-t, a --branch
hozzáadásával a clone parancshoz a tag nevét használhatjuk az ág neve helyett. A Git tudja, hogyan kell "lefordítani" a megadott SHA-1-et a megfelelő commitra.
# Clone a specific tag name using git clone
git clone <url> --branch=<tag_name>
git clone --branch=
--branch
is tud címkéket fogadni és leválasztja a HEAD-et az adott commitnál az eredményül kapott repositoryban.
git push --tags
Az összes címke pusholása:
git push --tags
A megjegyzésekkel ellátott címkék és az aktuális előzménylánc-címkék tologatásához használja a következőt::
git push --follow-tags
Ez a flag ---follow-tags
mind a commits, mind pedig a only tags, amelyek mindkettő:
A Git 2.4-től a konfigurációval beállítható
git config --global push.followTags true
Nem létezik olyan, hogy "távoli Git tag". Csak "címkék" vannak. Mindezt nem azért mondom el, hogy pedáns legyek,1 hanem azért, mert az alkalmi Git-felhasználók körében nagy a zűrzavar ezzel kapcsolatban, és a Git dokumentációja nem túl hasznos2 a kezdők számára. (Nem világos, hogy a zavar a rossz dokumentáció miatt van-e, vagy a rossz dokumentáció azért van, mert ez eleve kissé zavaros, vagy mi.)
Léteznek "távoli ágak", helyesebben "távoli nyomon követő ágak", de érdemes megjegyezni, hogy ezek valójában helyi entitások. Távoli címkék viszont nincsenek (hacsak nem (újra)találod őket). Csak helyi címkék léteznek, tehát a címkét helyileg kell megszerezned ahhoz, hogy használni tudd.
A konkrét commitok nevének általános formája - amit a Git referenciáknak nevez - bármelyik refs/
kezdetű karakterlánc. A refs/heads/
-vel kezdődő string egy ágat nevez el; a refs/remotes/
-vel kezdődő string egy távoli követést végző ágat; a refs/tags/
-vel kezdődő string pedig egy taget. A refs/stash
név a tárolóhivatkozás (ahogyan a git stash
használja; figyeljük meg, hogy hiányzik a záróvessző).
Van néhány szokatlan speciális esetű név, amely nem refs/
-vel kezdődik: a HEAD
, ORIG_HEAD
, MERGE_HEAD
és különösen a CHERRY_PICK_HEAD
mind olyan nevek, amelyek konkrét commitokra utalhatnak (bár a HEAD
általában egy ág nevét tartalmazza, azaz tartalmazza a ref: refs/heads/branch
). De általában a hivatkozások refs/
-vel kezdődnek.
Az egyik dolog, amit a Git tesz, hogy ez zavarossá tegye, hogy lehetővé teszi a refs/
elhagyását, és gyakran a refs/
utáni szót is. Például kihagyhatod a refs/heads/
vagy a refs/tags/
szót, amikor egy helyi ágra vagy tagre hivatkozol - és valójában kell kihagynod a refs/heads/
szót, amikor egy helyi ágat ellenőrzöl! Ezt akkor teheted meg, ha az eredmény egyértelmű, vagy - ahogy az imént megjegyeztük - ha muszáj megtenned (a git checkout branch
esetében).
Igaz, hogy a hivatkozások nem csak a saját tárolódban léteznek, hanem távoli tárolókban is. A Git azonban csak nagyon meghatározott időpontokban ad hozzáférést egy távoli tárolóhoz'a referenciákhoz: nevezetesen a fetch
és push
műveletek során. A git ls-remote
vagy a git remote show
segítségével is láthatod őket, de a fetch
és a push
az érdekesebb érintkezési pontok.
A fetch
és push
műveletek során a Git refspecs-nek nevezett karakterláncokat használ a helyi és a távoli tároló közötti referenciák átvitelére. Így ezekben az időpontokban, és a refspecsek segítségével két Git-tárhely szinkronizálódhat egymással. Ha a nevek szinkronban vannak, akkor ugyanazt a nevet használhatod, amit valaki a távolival használ. Van itt azonban némi különleges varázslat a fetch
-nél, és ez mind az ágnevekre, mind a tagnevekre hatással van.
A git fetch
-re úgy kell gondolnod, hogy a Git-ed arra utasítja, hogy hívjon fel (vagy esetleg küldjön szöveges üzenetet) egy másik Git-et - a "távoli"-t - és beszélgessen vele. A beszélgetés elején a távoli rendszer felsorolja az összes referenciáját: mindent, ami a refs/heads/
-ben és mindent, ami a refs/tags/
-ben van, valamint minden más referenciát, amivel rendelkezik. A Gited átnézi ezeket, és (a szokásos fetch refspec alapján) átnevezi az águkat.
Nézzük meg a origin
nevű távolira vonatkozó normál refspec-et:
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$
Ez a refspec utasítja a Git-et, hogy vegyen minden olyan nevet, amelyik megfelel a refs/heads/*
- azaz minden ágat a távoliban- és változtassa meg a nevét refs/remotes/origin/*
-re, azaz tartsa meg az illeszkedő részt, az ág nevét (refs/heads/
) változtassa meg egy távoli nyomon követhető ág nevére (refs/remotes/
, konkrétan refs/remotes/origin/
).
Ez ezen refspec révén lesz a origin
'ágakból a távoli origin
távoli követési ága. Az ágnév a távkövető ág nevévé válik, a távoli, ebben az esetben a origin
nevével együtt. A refspec elején lévő +
pluszjel a "force" jelzőt állítja be, azaz a távkövető ágad úgy frissül, hogy megfeleljen a távoli ág nevének, függetlenül attól, hogy mit kell tenned, hogy megfeleljen. (A +
nélkül az ágak frissítései a "gyors továbbítás" módosításokra korlátozódnak, és a címkék frissítéseit a Git 1.8.2-es verziója óta egyszerűen figyelmen kívül hagyja - előtte ugyanezek a gyors továbbítási szabályok voltak érvényben).
De mi a helyzet a címkékkel? Nincsenek refspec-ek - legalábbis alapértelmezés szerint nem. Beállíthatsz egyet, ebben az esetben a refspec formája rajtad múlik; vagy futtathatod a git fetch --tags
parancsot. A --tags
használata azt eredményezi, hogy a refspec-hez hozzáadjuk a refs/tags/*:refs/tags/*
-t, azaz, átviszi az összes címkét (de nem frissíti a te címkéidet, ha már van egy ilyen nevű címkéd, függetlenül attól, hogy a távoli címke mit mond Szerkesztés, 2017. január: a Git 2-től.10, a tesztelés azt mutatja, hogy a --tags
erőszakkal frissíti a te címkédet a távoli's címkékből, mintha a refspec +refs/tags/*:refs/tags/*
lenne; ez lehet, hogy a Git egy korábbi verziójához képest eltérő viselkedés).
Vedd figyelembe, hogy itt nincs átnevezés: ha a távoli origin
-ben van xyzzy
tag, és neked nincs, és te git fetch origin "refs/tags/*:refs/tags/*"
, akkor a refs/tags/xyzzy
hozzáadódik a te tárolódhoz (ugyanarra a commitra mutatva, mint a távoliban). Ha a +refs/tags/*:refs/tags/*
-t használod, akkor a xyzzy
címke, ha van, *helyettesítve lesz a origin
címkéjével. Vagyis a +
force flag egy refspec-en azt jelenti, hogy "cseréld le a hivatkozásom'értékét arra, amit a Git-em a saját Git-jéből kap".
Történelmi okokból,3 ha nem használod sem a --tags
opciót, sem a --no-tags
opciót, a git fetch
különleges lépéseket tesz. Emlékezz, hogy fentebb azt mondtuk, hogy a távoli azzal kezdi, hogy a helyi Gitednek minden hivatkozását megjeleníti, függetlenül attól, hogy a helyi Gited látni akarja-e őket vagy sem.4 A Gited ezen a ponton megjegyzi az összes taget, amit lát. Ezután, amikor elkezdi letölteni az összes commit objektumot, amire szüksége van ahhoz, hogy kezelje, amit lekérdez, ha az egyik ilyen commitnak ugyanaz az azonosítója, mint bármelyik címkének, akkor a git hozzáadja azt a taget - vagy ezeket a címkéket, ha több tagnek is megvan ez az azonosítója - a tárolódhoz.
Szerkesztés, 2017. január: a tesztelés azt mutatja, hogy a viselkedés a Git 2.10-ben most: Ha az ő Gitjük biztosít egy T nevű taget, és neked nincs T nevű taged, és a T-hez tartozó commit ID egy őse az egyik águknak, amit a git fetch
vizsgál, akkor a Gited hozzáadja T-t a tagjeidhez --tagekkel
vagy anélkül. A --tags
hozzáadásával a Gited minden címkéjüket megszerzi, és a frissítést is kikényszeríti.
Lehet, hogy a git fetch --tags
-t kell használnod, hogy megkapd a címkéiket. Ha a címkenevek ütköznek a meglévő címkenevekkel, lehet (a Git verziójától függően) még törölnöd (vagy átnevezned) is kell néhány címkét, majd futtatnod a git fetch --tags
-t, hogy megkapd a címkéiket. Mivel a címkék - a távoli ágakkal ellentétben - nem rendelkeznek automatikus átnevezéssel, a címkék nevének meg kell egyeznie az ő címkéik nevével, ezért lehetnek konfliktusos problémák.
A többnyire normális esetekben azonban egy egyszerű git fetch
elvégzi a munkát, átveszi a commitjaikat és a hozzájuk tartozó címkéket, és mivel ők - bárkik is legyenek azok - a commitokat akkor címkézik, amikor publikálják azokat, te is lépést tartasz a címkékkel. Ha nem készítesz saját címkéket, és nem kevered a repositoryjukat más repositorykkal (több távoli elérésen keresztül), akkor nem lesznek címke név ütközések sem, így nem kell a címkék törlésével vagy átnevezésével bajlódnod ahhoz, hogy megkapd a címkéiket.
Fentebb említettem, hogy a refs/
szinte mindig elhagyható, a refs/heads/
és refs/tags/
és így tovább pedig a legtöbbször. De mikor nem lehet?
A teljes (vagy legalábbis majdnem teljes) választ a gitrevisions
dokumentációban találod. A Git a linkben megadott hat lépésből álló szekvencia segítségével oldja fel a nevet commit azonosítóra. Érdekes módon a címkék felülírják az ágakat: ha van egy xyzzy
címke és egy xyzzy
ág, és ezek különböző commitokra mutatnak, akkor:
git rev-parse xyzzy
gitrevisions
-ból - a git checkout
az ágneveket részesíti előnyben, így a git checkout xyzzy
az ágra fog helyezni, figyelmen kívül hagyva a taget.
Kétértelműség esetén szinte mindig kiírhatod a ref nevét a teljes nevével, refs/heads/xyzzy
vagy refs/tags/xyzzy
. (Megjegyzendő, hogy ez működik a git checkout
tal, de talán váratlan módon: A git checkout refs/heads/xyzzy
inkább egy detached-HEAD checkoutot okoz, mint egy branch checkoutot. Ezért csak azt kell megjegyezned, hogy a git checkout
először a rövid nevet fogja ágnévként használni: így'így checked ki az xyzzy
ágat akkor is, ha a xyzzy
tag létezik. Ha ki akarod csekkolni a taget, használhatod a refs/tags/xyzzy
-t).
Mivel (ahogy a gitrevisions
megjegyzi) a Git megpróbálja a refs/name
, egyszerűen írhatod a tags/xyzzy
-t is a xyzzy
címkével ellátott commit azonosítására. (Ha azonban valakinek sikerült egy xyzzy
nevű érvényes hivatkozást írnia a $GIT_DIR
-be, akkor ez $GIT_DIR/xyzzy
-ként fog feloldódni. Normális esetben azonban csak a különböző *HEAD
neveknek kellene a $GIT_DIR
-ben lenniük.)1Oké, oké, "nem csak azért, hogy pedáns legyek" :-)
2Egyesek szerint "nagyon nem segítőkész", és én inkább egyetértenék vele.
3Alapvetően a git fetch
, és a remotes és refspecs egész koncepciója egy kicsit későn került a Git-be, a Git 1.5 körül történt. Előtte csak néhány ad-hoc speciális eset volt, és a tag-fetching volt az egyik ilyen, így speciális kóddal került be a rendszerbe.
4Ha ez segít, gondolj a távoli Gitre úgy, mint egy flasher, szleng értelemben.
Az adott címkekód megszerzéséhez próbáljon meg létrehozni egy új ágat, és adja hozzá a címkekódot.
Ezt a következő paranccsal csináltam: $git checkout -b newBranchName tagName
.