„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 pull
tik 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_BRANCH
dalis 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 pull
su neįvykdytais pakeitimais galite patekti į bėdą. Laimei, yra būdų, kaip išsivaduoti iš bėdos iš vieno gabalo!

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 merge
dirbti.
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 stash
sukuria į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 pop
komandą. 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 fetch
yra 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.