git push: jinsi ya kutuma mabadiliko kwenye hifadhi ya mbali
git push inatuma commits za tawi la sasa ambazo hazipo kwenye seva kwenye hifadhi ya mbali (kwa kawaida origin), na kusogeza kielekezi cha tawi kule. Mara ya kwanza tawi linachapishwa kwa git push -u origin jina-la-tawi, baadaye inatosha git push. Ikiwa kwenye seva kuna commits za wengine, kwanza vuta kwa git pull, si force push.
Git push inafanya nini
Amri git push inachukua commits kutoka tawi lako la ndani ambazo bado hazipo kwenye seva, zinazipeleka kwenye hifadhi ya mbali (kwa kawaida inaitwa origin), na kusogeza kielekezi cha tawi huko hadi commit yako ya mwisho. Faili za saraka ya kazi na mabadiliko ambayo hayajawekwa commit hayaendi popote: kinachotumwa ni historia, yaani commits.
Ni muhimu kuelewa kwamba push si «usawazishaji». Inafanya kazi upande mmoja: kutoka hifadhi ya ndani kwenda ya mbali. Ili kupata mabadiliko ya wengine unahitaji git fetch au git pull. Mkanganyiko wa mwelekeo huu ndio chanzo cha karibu matatizo yote ambayo wanaoanza huyapeleka kwa mshauri.
Kanuni nyingine ya Git: kwa chaguo-msingi push inaruhusiwa tu kama «kusogea mbele» (fast-forward). Seva itakubali commits zako ikiwa zinaendeleza historia iliyopo tayari kwenye seva. Mtu mwingine akiwa ametuma commits zake kabla yako, push yako itakataliwa — na hiyo ni kinga, si hitilafu.
Muundo wa amri
git push [<remote>] [<tawi-la-ndani>[:<tawi-la-mbali>]]
Ukiita git push bila hoja, Git inachukua tawi la sasa na kulituma kwenye tawi lililowekwa kama upstream (linalofuatiliwa). Fomu ya wazi ni muhimu wakati upstream bado haijawekwa, au unataka kutuma tawi chini ya jina tofauti:
git push origin main # tuma main ya ndani kwenda origin/main
git push origin feature/login # tuma tawi feature/login
git push origin fix:hotfix-123 # tuma fix ya ndani kama hotfix-123 kwenye seva
git push origin HEAD # tuma tawi la sasa kwa jina lilelile
Jinsi ya kutuma mabadiliko mara ya kwanza
Njia ya kawaida kutoka mradi mpya hadi msimbo kwenye GitHub au GitLab inaonekana hivi. Kwanza unaunda hifadhi tupu kwenye seva, kisha unaiunganisha na ile ya ndani na kutuma tawi.
git init
git add .
git commit -m "Commit ya kwanza"
git branch -M main
git remote add origin git@github.com:user/project.git
git push -u origin main
Bendera -u (fomu kamili --set-upstream) inaunganisha tawi la ndani main na la mbali origin/main. Baada ya hapo ndani ya tawi unaweza kuandika tu git push na git pull, na git status itaanza kuonyesha umetangulia au umebaki nyuma ya seva kwa commits ngapi.
Kuhakiki hifadhi ya mbali inaelekeza wapi, tumia git remote -v. Ikiwa anwani si sahihi, irekebishe kwa git remote set-url origin <anwani-mpya>, badala ya kufuta na kuunda hifadhi upya.
Jinsi ya kutuma tawi jipya
Umeunda tawi kwa ajili ya kazi, umefanya commits, na unaandika git push. Git inajibu:
fatal: The current branch feature/login has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin feature/login
Hii si hitilafu, ni dokezo: tawi bado halina jozi kwenye seva. Tekeleza amri iliyopendekezwa, au fomu fupi git push -u origin feature/login. Ili Git ifanye hivi kiotomatiki kwa matawi yote mapya, washa mpangilio (unapatikana Git 2.37 na zaidi):
git config --global push.autoSetupRemote true
Kwa nini git push imekataliwa: rejected, non-fast-forward
Hali inayojitokeza zaidi katika kazi ya timu:
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:user/project.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally.
Mwenzako ametuma commits zake kabla yako. Historia yako na ile ya seva zimetengana, na kama Git ingekubali push yako, commits za mwenzako zingepotea. Suluhisho sahihi ni kwanza kuvuta mabadiliko na kuunganisha zako ndani yake:
git pull --rebase # vuta commits za wengine na upange zako juu yake
# conflicts: rekebisha faili, git add, git rebase --continue
git push
Badala ya --rebase unaweza kutumia git pull ya kawaida — hapo itaundwa commit ya muunganisho. Chaguzi zote mbili ni sahihi; timu nyingi zinapendelea rebase kwa commits zako za ndani ili historia ibaki mstari mmoja. Jambo kuu: usitatue kukataliwa kwa --force.
git push --force na --force-with-lease
Force push inahitajika pale unapoandika upya historia ya tawi lako kwa makusudi: umefanya git commit --amend, git rebase, au umeunganisha commits kabla ya ukaguzi. Push ya kawaida haitakubali tawi kama hilo, kwa sababu commits za zamani kwenye seva si mababu tena wa zile mpya.
git push --force-with-lease
--force-with-lease inaandika upya tawi kwenye seva tu ikiwa liko mahali pale ambapo Git yako ya ndani ililiona mara ya mwisho (kwa rejeo la origin/<tawi>). Mtu akiwa ametuma kitu, amri inakataa, na hutafuta kazi yake. --force (-f) ya kawaida haina ukaguzi huo na inaandika juu ya kila kitu kimya kimya.
Kuna tahadhari: ukifanya git fetch kabla ya force push, rejeo la origin/<tawi> linasasishwa, na ulinzi unaacha kufanya kazi — Git itafikiri umeona commits za wengine. Kwa hiyo usifanye fetch moja kwa moja kabla ya force push bila kuangalia kilichofika.
| Amri | Inafanya nini | Lini kutumia |
|---|---|---|
git push | Fast-forward pekee | Daima kwa chaguo-msingi |
git push --force-with-lease | Kuandika upya kwa ukaguzi | Tawi lako baada ya rebase au amend |
git push --force | Kuandika upya bila ukaguzi | Karibu kamwe; kamwe kwenye matawi ya pamoja |
Kwenye matawi ya pamoja (main, develop) force push haziruhusiwi: kila aliyekwisha kupakua historia ya zamani atatofautiana na seva. Matawi haya kwa kawaida pia yanalindwa kwa mipangilio ya hifadhi, na seva itajibu protected branch hook declined.
Jinsi ya kutuma tagi
Push ya kawaida haitumi tagi. Zinatumwa waziwazi:
git tag -a v1.2.0 -m "Toleo 1.2.0"
git push origin v1.2.0 # tagi moja
git push --tags # tagi zote za ndani
git push --follow-tags # commits na tagi zilizofafanuliwa zinazoelekeza kwenye commits hizo
--follow-tags ni bora kuliko --tags: haitumi tagi nyepesi za bahati mbaya, bali zile zilizofafanuliwa tu, na zile tu zinazoweza kufikiwa kutoka commits zinazotumwa.
Jinsi ya kufuta tawi kwenye seva
Kufuta pia kunafanyika kwa push:
git push origin --delete feature/login
# sintaksia ya zamani, inafanya kitu kile kile:
git push origin :feature/login
Tawi la ndani linabaki, na kulifuta kunawezekana kwa git branch -d feature/login. Wenzako bado watakuwa na rejeo la origin/feature/login, mpaka watekeleze git fetch --prune.
Bendera muhimu za git push
| Bendera | Maana yake |
|---|---|
-u, --set-upstream | Kukumbuka tawi la mbali kama upstream |
-n, --dry-run | Kuonyesha kitakachotumwa bila kutuma chochote |
--all | Kutuma matawi yote ya ndani |
--tags / --follow-tags | Kutuma tagi |
-d, --delete | Kufuta tawi au tagi kwenye seva |
--force-with-lease | Kuandika upya historia kwa usalama |
-v, --verbose | Matokeo ya kina |
--no-verify | Kuruka hook ya pre-push (itumike kwa makusudi) |
Makosa ya kawaida ya git push na suluhisho lake
Permission denied (publickey)
Seva haijakubali ufunguo wako wa SSH. Hakiki kwamba ufunguo upo (ls ~/.ssh), kwamba sehemu ya umma imeongezwa kwenye akaunti, na kwamba muunganisho unafanya kazi: ssh -T git@github.com. Ikiwa remote imeandikwa kwa HTTPS, Git itaomba jina la mtumiaji na token badala ya ufunguo — angalia git remote -v.
Authentication failed kwa HTTPS
GitHub na huduma nyingine nyingi hazikubali tena nywila ya akaunti kwa HTTPS. Unahitaji token ya ufikiaji ya kibinafsi, au kubadili kwenda SSH. Msaidizi wa kuhifadhi taarifa za kuingia unasaidia: git config --global credential.helper store (huhifadhi kwa maandishi wazi) au meneja wa taarifa za kuingia wa mfumo wako.
src refspec main does not match any
Huna tawi lenye jina hilo. Mara nyingi hifadhi tupu bado haina commit hata moja, au tawi linaitwa master. Hakiki kwa git branch kisha fanya commit, au badilisha jina la tawi: git branch -M main.
Everything up-to-date, ingawa mabadiliko yapo
Umesahau kuweka commit. git push inatuma commits, si faili. Tekeleza git status, kisha git add na git commit. Chaguo jingine ni kwamba uko kwenye tawi tofauti na unalotarajia kuona kwenye seva.
Faili kubwa mno
Huduma zinaweka kikomo cha ukubwa wa faili (kwenye GitHub — MB 100). Faili kama hilo likiingia kwenye historia, haitoshi kulifuta kwa commit mpya: unahitaji kuandika upya historia au kuliondoa kwenye commits ambazo bado hazijatumwa (git reset --soft, kisha commit upya). Kwa faili kubwa za binary tumia Git LFS.
Mzunguko wa kazi kwa git push
git switch -c feature/x— tawi kwa ajili ya kazi.- Commits ndogo zenye hatua za kimantiki.
git fetchnagit rebase origin/main— kuvuta tawi kuu jipya.git push -u origin feature/x— kuchapisha tawi.- Kufungua pull request, baada ya ukaguzi — commits za ziada na
git pushya kawaida. - Ikibidi kuandika upya historia —
git push --force-with-lease.
Kabla ya kutuma ni vizuri kuona kitakachoenda kwenye seva: git log origin/main..HEAD --oneline inaonyesha commits ambazo bado hazipo kwenye seva.
Mipangilio ya kuweka mara moja
Mipangilio michache ya kimataifa inaondoa mshangao mwingi wakati wa kutuma. push.default inaamua kitakachotumwa na git push bila hoja. Thamani ya chaguo-msingi kwenye matoleo ya sasa ni simple: linatumwa tawi la sasa tu, na tu kwenye tawi lenye jina hilo hilo kama upstream. Mara nyingi hakuna haja ya kulibadilisha, lakini angalia kwamba usanidi wa zamani haujabaki na matching, inayotuma matawi yote yanayolingana kwa jina mara moja.
git config --global push.default simple
git config --global push.autoSetupRemote true
git config --global push.followTags true
git config --global pull.rebase true
push.followTags inafanya --follow-tags kuwa tabia ya chaguo-msingi, na pull.rebase inaondoa commits zisizo za lazima za muunganisho pale push inapokataliwa na unahitaji kwanza kuvuta mabadiliko ya wengine.
Hook ya pre-push
Faili .git/hooks/pre-push linatekelezwa kabla ya kutuma. Likimaliza kwa msimbo usio sifuri, push haitafanyika. Mara nyingi timu huweka humo majaribio au linter, ili msimbo uliovunjika usiende kwenye seva. Kuruka hook kwa --no-verify ni kwa wakati tu unapoelewa kwa nini unaanguka.
Muhtasari
git push inachapisha commits zako kwenye hifadhi ya mbali, na inafanya kazi upande mmoja tu. Tuma tawi mara ya kwanza ukiwa na -u; kikikataliwa, kwanza vuta mabadiliko ya wengine kwa pull; na historia ya tawi lako iliyoandikwa upya itumwe kwa --force-with-lease pekee. Kazi na hifadhi za mbali, push, pull na funguo za SSH vimefafanuliwa kwa vitendo katika kozi ya Git.
Maswali ya mara kwa mara
Je, git push inatuma mabadiliko ambayo hayajawekwa commit?
Hapana. Push inatuma commits pekee; mabadiliko kwenye saraka ya kazi na index yanabaki kwenye kompyuta yako hadi uyawekee commit.
Nawezaje kughairi git push?
Kwenye tawi lako unaweza kughairi commit ndani (git reset) na kutuma kwa git push --force-with-lease. Kwenye tawi la pamoja ni salama zaidi kuunda commit ya kinyume kwa git revert na kufanya push ya kawaida.
Je, inawezekana kutuma commit moja tu?
Ndiyo, kwa kutaja hash yake: git push origin abc1234:main itatuma historia yote hadi commit hiyo ikijumuishwa, lakini si commits za baadaye. Commit haiwezi kutumwa bila mababu zake.
git push inatofautianaje na git push origin main?
Bila hoja Git inatumia upstream iliyowekwa ya tawi la sasa, wakati fomu wazi inataja remote na tawi moja kwa moja, na inafanya kazi hata kama upstream haijawekwa.
Nawezaje kutuma kwenye hifadhi mbili kwa wakati mmoja?
Ongeza remote ya pili na utume kwa jina lake, au ongeza anwani mbili za push kwa origin kwa amri git remote set-url --add --push origin anwani (fanya kwa anwani zote mbili, ikiwemo ya asili, vinginevyo push itaenda kwa ile ya pili pekee).
Mada hii inafundishwa kwa kina pamoja na mazoezi katika kozi “Git kutoka mwanzo hadi msanidi programu anayejiweza”.
Nenda kwenye kozi