„Git Pull Force“ - kaip perrašyti vietinius pokyčius naudojant „Git“

Išmokę koduoti, anksčiau ar vėliau sužinosite ir apie versijų valdymo sistemas. Nors šioje erdvėje yra daugybė konkuruojančių įrankių, vienas iš jų yra de facto standartas, kurį naudoja beveik visi pramonės atstovai. Tai taip populiaru, kad yra įmonių, kurios naudoja savo vardą savo prekės ženkle. Mes, žinoma, apie Gitą.

Nors „Git“ yra galingas įrankis, jo galia yra gerai paslėpta. Yra keletas esminių sąvokų, kurias turite suprasti, kad galėtumėte iš tikrųjų mokėti naudotis „Git“. Geros naujienos yra tai, kad išmokę juos, vargu ar kada susidursite su bėdomis, nuo kurių negalėsite pabėgti.

Tipinė darbo eiga

Įprastoje „Git“ darbo eigoje naudosite vietinę saugyklą, nuotolinę talpyklą ir vieną ar daugiau šakų. Saugyklose saugoma visa informacija apie projektą, įskaitant visą jo istoriją ir visas šakas. Filialas iš esmės yra pokyčių, vedančių iš tuščio projekto į dabartinę būseną, rinkinys.

Klonavę saugyklą, dirbate su savo vietine kopija ir pristatote naujus pakeitimus. Kol nepajudinsite vietinių nuotolinės saugyklos pakeitimų, visi jūsų darbai bus pasiekiami tik jūsų kompiuteryje.

Baigę užduotį, laikas sinchronizuoti su nuotolinio saugykla. Jei norite neatsilikti nuo projekto pažangos, norite atlikti nuotolinius pakeitimus, o vietinius pakeitimus norite pasidalinti savo darbu su kitais.

Vietiniai pokyčiai

Viskas gerai, kai jūs ir visa jūsų komanda dirbate su visiškai atskirais failais. Kad ir kas nutiktų, jūs nestosite vienas kitam ant kojų.

Tačiau yra atvejų, kai jūs ir jūsų komandos draugai vienu metu įveskite pakeitimus toje pačioje vietoje. Ir dažniausiai ten prasideda problemos.

Ar jūs kada nors įvykdėte mirties bausmę git pulltik tam, kad pamatytumėte baimę error: Your local changes to the following files would be overwritten by merge:? Anksčiau ar vėliau visi susiduria su ta problema.

Čia dar painiau tai, kad nenorite nieko sujungti, tiesiog traukite, tiesa? Tiesą sakant, traukimas yra šiek tiek sudėtingesnis, nei galėjai pagalvoti.

Kaip tiksliai veikia „Git Pull“?

Traukimas nėra viena operacija. Tai susideda iš duomenų gavimo iš nuotolinio serverio ir tada pakeitimų sujungimo su vietine saugykla. Šias dvi operacijas galima atlikti rankiniu būdu, jei norite:

git fetch git merge origin/$CURRENT_BRANCH

Į origin/$CURRENT_BRANCHdalis reiškia, kad:

  • „Git“ sujungs pakeitimus iš pavadintos nuotolinės saugyklos origin(tos, iš kurios klonavote)
  • kurie buvo pridėti prie $CURRENT_BRANCH
  • kurių dar nėra jūsų vietiniame patikrintame skyriuje

Kadangi „Git“ sujungimus vykdo tik tada, kai nėra neįvykdytų pakeitimų, kaskart paleisdami git pullsu neįvykdytais pakeitimais galite patekti į bėdą. Laimei, yra būdų, kaip išsivaduoti iš bėdos iš vieno gabalo!

Mes esame šeima

Skirtingi požiūriai

Kai neatlikote vietinių pakeitimų ir vis tiek norite iš nuotolinio serverio išsirinkti naują versiją, jūsų naudojimo atvejis paprastai patenka į vieną iš šių scenarijų. Arba:

  • jums nerūpi vietiniai pokyčiai ir norite juos perrašyti,
  • jums labai rūpi pakeitimai ir norėtumėte juos pritaikyti po nuotolinių pakeitimų,
  • norite atsisiųsti nuotolines modifikacijas, bet jų dar netaikote

Kiekvienam požiūriui reikalingas skirtingas sprendimas.

Jums nerūpi vietiniai pokyčiai

Tokiu atveju jūs tiesiog norite atsisakyti visų neįvykdytų vietinių pakeitimų. Galbūt pakeitėte failą, kad galėtumėte eksperimentuoti, bet modifikuoti jums nebereikia. Viskas, kas jums rūpi, yra atnaujinimas su tiekėjais.

Tai reiškia, kad pridedate dar vieną žingsnį tarp nuotolinių pakeitimų gavimo ir jų sujungimo. Atlikus šį veiksmą filialas bus atstatytas į nepakeistą būseną, taigi bus galima git mergedirbti.

git fetch git reset --hard HEAD git merge origin/$CURRENT_BRANCH

Jei nenorite įvesti filialo pavadinimą, kiekvieną kartą paleidus šią komandą, Git turi gražią nuorodą nukreipta į tiekėjų šakos: @{u}. Aukštyn esanti šaka yra nuotolinės saugyklos šaka, į kurią stumiate ir iš kurios gaunate.

Štai kaip pirmiau minėtos komandos atrodys naudojant spartųjį klavišą:

git fetch git reset --hard HEAD git merge '@{u}'

Mes cituojame pavyzdyje pateiktą nuorodą, kad apvalkalas negalėtų jos interpretuoti.

Jums labai rūpi vietiniai pokyčiai

Kai neįvykdyti pakeitimai jums yra reikšmingi, yra dvi galimybės. Galite juos įsipareigoti ir tada atlikti git pull, arba galite juos palikti.

Stabdymas reiškia akimirkos atidėjimą pakeitimams, kad jie vėl būtų grąžinti. Tiksliau, git stashsukuria įsipareigojimą, kuris nėra matomas dabartiniame jūsų filiale, bet vis tiek prieinamas „Git“.

Norėdami grąžinti pakeitimus, išsaugotus paskutinėje atmintyje, naudokite git stash popkomandą. Sėkmingai pritaikius paslėptus pakeitimus, ši komanda taip pat pašalina įvykdymą, nes jis nebereikalingas.

Tada darbo eiga gali atrodyti taip:

git fetch git stash git merge '@{u}' git stash pop

Pagal numatytuosius nustatymus pakeitimai iš saugyklos bus surežisuoti. Jei norite juos pašalinti, naudokite komandą git restore --staged(jei naudojate „Git“ naujesnę nei 2.25.0).

Jūs tiesiog norite atsisiųsti nuotolinius pakeitimus

Paskutinis scenarijus šiek tiek skiriasi nuo ankstesnių. Tarkime, kad jūs esate labai netvarkingo pertvarkymo viduryje. Nei prarasti pakeitimų, nei jų sustabdyti nėra galimybės. Vis tiek norite, kad nuotoliniai pakeitimai būtų prieinami, kad būtų galima juos paleisti git diff.

Kaip tikriausiai supratote, atsisiųsti nuotolinių pakeitimų visiškai nereikia git pull! git fetchyra tiesiog pakankamai.

One thing to note is that by default, git fetch will only bring you changes from the current branch. To get all the changes from all the branches, use git fetch --all. And if you'd like to clean up some of the branches that no longer exist in the remote repository, git fetch --all --prune will do the cleaning up!

Some Automation

Have you heard of Git Config? It's a file where Git stores all of the user-configured settings. It resides in your home directory: either as ~/.gitconfig or ~/.config/git/config. You can edit it to add some custom aliases that will be understood as Git commands.

For example, to have a shortcut equivalent to git diff --cached (that shows the difference between the current branch and the staged files), you'd add the following section:

[alias] dc = diff --cached

After that, you can run git dc whenever you wish to review the changes. Going this way, we can set up a few aliases related to the previous use cases.

[alias] pull_force = !"git fetch --all; git reset --hard HEAD; git merge @{u}" pf = pull_force pull_stash = !"git fetch --all; git stash; git merge @{u}; git stash pop"

This way, running git pull_force will overwrite the local changes, while git pull_stash will preserve them.

The Other Git Pull Force

Curious minds may have already discovered that there is such a thing as git pull --force. However, this is a very different beast to what's presented in this article.

It may sound like something that would help us overwrite local changes. Instead, it lets us fetch the changes from one remote branch to a different local branch. git pull --force only modifies the behavior of the fetching part. It is therefore equivalent to git fetch --force.

Like git push, git fetch allows us to specify which local and remote branch do we want to operate on. git fetch origin/feature-1:my-feature will mean that the changes in the feature-1 branch from the remote repository will end up visible on the local branch my-feature. When such an operation modifies the existing history, it is not permitted by Git without an explicit --force parameter.

Just like git push --force allows overwriting remote branches, git fetch --force (or git pull --force) allows overwriting local branches. It is always used with source and destination branches mentioned as parameters. An alternative approach to overwriting local changes using git --pull force could be git pull --force "@{u}:HEAD".

Conclusion

Gito pasaulis yra didžiulis. Šis straipsnis apėmė tik vieną iš saugyklos priežiūros aspektų: nuotolinių pakeitimų įtraukimą į vietinę saugyklą. Net šis kasdienis scenarijus pareikalavo šiek tiek nuodugniau pažvelgti į šios versijos valdymo įrankio vidinius mechanizmus.

Sužinoję faktinio naudojimo atvejus, galite geriau suprasti, kaip „Git“ veikia po gaubtu. Tai savo ruožtu leis jaustis įgalintais, kai tik pateksite į bėdą. Mes visi kartkartėmis tai darome.