Git Pull Force - kā pārrakstīt vietējās izmaiņas ar Git

Mācoties kodēt, agrāk vai vēlāk jūs uzzināsiet arī par versiju vadības sistēmām. Un, lai gan šajā telpā ir daudz konkurējošu rīku, viens no tiem ir de facto standarts, ko izmanto gandrīz visi nozares pārstāvji. Tas ir tik populārs, ka ir uzņēmumi, kas izmanto tā nosaukumu zīmolu veidošanā. Mēs, protams, runājam par Gitu.

Kaut arī Git ir spēcīgs rīks, tā spēks ir labi paslēpts. Ir daži būtiski jēdzieni, kas jums ir jāsaprot, lai kļūtu patiešām lietpratīgs ar Gitu. Labā ziņa ir tā, ka pēc to iemācīšanās jūs diez vai kādreiz nonāksiet nepatikšanās, no kurām nevarat izvairīties.

Tipiskā darbplūsma

Tipiskā Git darbplūsmā izmantosiet vietējo repozitoriju, attālo repozitoriju un vienu vai vairākas filiāles. Krātuvēs tiek glabāta visa informācija par projektu, ieskaitot visu tā vēsturi un visas filiāles. Filiāle būtībā ir izmaiņu kopums, kas ved no tukša projekta uz pašreizējo stāvokli.

Pēc repozitorija klonēšanas jūs strādājat ar vietējo kopiju un ieviešat jaunas izmaiņas. Kamēr vietējās izmaiņas nenorādīsit uz attālo krātuvi, viss jūsu darbs ir pieejams tikai jūsu datorā.

Kad esat pabeidzis uzdevumu, ir pienācis laiks sinhronizēt ar attālo repozitoriju. Jūs vēlaties izvilkt attālās izmaiņas, lai neatpaliktu no projekta progresa, un vēlaties virzīt vietējās izmaiņas, lai dalītos savā darbā ar citiem.

Vietējās izmaiņas

Viss ir kārtībā, kad jūs un pārējā komanda strādājat pie pilnīgi atsevišķiem failiem. Lai kas arī notiktu, jūs neuzkāpsit viens otram uz kājām.

Tomēr ir gadījumi, kad jūs un jūsu komandas biedri vienlaikus veicat izmaiņas vienā un tajā pašā vietā. Un parasti tur sākas problēmas.

Vai jūs kādreiz esat izpildījis nāvessodu git pulltikai tāpēc, lai redzētu baidītos error: Your local changes to the following files would be overwritten by merge:? Agrāk vai vēlāk visi saskaras ar šo problēmu.

Šeit vairāk mulsina tas, ka jūs nevēlaties neko apvienot, vienkārši velciet, vai ne? Patiesībā pull ir mazliet sarežģītāka, nekā jūs varētu domāt.

Cik precīzi darbojas Git Pull?

Vilkšana nav viena operācija. Tas sastāv no datu ielādes no attālā servera un pēc tam izmaiņu apvienošanas ar vietējo repozitoriju. Šīs divas darbības var veikt manuāli, ja vēlaties:

git fetch git merge origin/$CURRENT_BRANCH

Par origin/$CURRENT_BRANCHdaļa nozīmē, ka:

  • Git apvienos izmaiņas no nosaukta attālā krātuves origin(tās, no kuras jūs klonējāt)
  • kas ir pievienoti $CURRENT_BRANCH
  • kas vēl nav jūsu vietējā reģistrētā filiālē

Tā kā Git apvieno tikai tad, ja nav neviena neizpildīta izmaiņa, katru reizi, kad palaižat git pullar neizpildītām izmaiņām, jūs varat sagādāt nepatikšanas. Par laimi, ir veidi, kā izkļūt no nepatikšanām vienā gabalā!

Mēs esam ģimene

Dažādas pieejas

Kad esat izdarījis vietējās izmaiņas un joprojām vēlaties izvilkt jaunu versiju no attālā servera, izmantošanas gadījums parasti ietilpst vienā no šiem scenārijiem. Arī:

  • jums nav nozīmes vietējām izmaiņām un vēlaties tās pārrakstīt,
  • jums ļoti svarīgas izmaiņas un vēlaties tās piemērot pēc attālinātām izmaiņām,
  • vēlaties lejupielādēt tālvadības modifikācijas, bet vēl tās nepiemērot

Katrai no pieejām ir nepieciešams atšķirīgs risinājums.

Jums nav nozīmes vietējām izmaiņām

Šajā gadījumā jūs vienkārši vēlaties atmest visas neizpildītās vietējās izmaiņas. Varbūt eksperimentējot modificējāt failu, taču modifikācija jums vairs nav nepieciešama. Viss, kas jums rūp, ir sekot līdzi augšpusei.

Tas nozīmē, ka jūs pievienojat vēl vienu soli starp attālo izmaiņu iegūšanu un to apvienošanu. Šis solis atjaunos filiāli nemodificētajā stāvoklī, tādējādi ļaujot git mergedarboties.

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

Ja jūs nevēlaties rakstīt filiāles nosaukums katru reizi palaižot šo komandu, Git ir jauka īsceļu norādot uz augšpus filiālē: @{u}. Augšpusējā filiāle ir filiāle attālajā krātuvē, uz kuru virzāties un no kuras atnest.

Šādi izskatīsies iepriekš minētās komandas ar saīsni:

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

Mēs citējam saīsni piemērā, lai neļautu čaulai to interpretēt.

Jums ļoti rūp vietējās izmaiņas

Kad jūsu neizpildītās izmaiņas jums ir nozīmīgas, ir divas iespējas. Jūs varat tos apņemties un pēc tam izpildīt git pull, vai arī varat tos atlicināt.

Izzināšana nozīmē pārmaiņu atlikšanu uz brīdi, lai tās vēlāk atgrieztos. Pareizāk sakot, git stashizveido apņemšanos, kas nav redzama jūsu pašreizējā filiālē, taču joprojām ir pieejama Gitam.

Lai atgrieztu pēdējā atlicinājumā saglabātās izmaiņas, izmantojiet git stash popkomandu. Pēc sekmīgas izmaiņu piemērošanas šī komanda arī noņem atlicināšanas atdevi, jo tā vairs nav nepieciešama.

Tad darbplūsma varētu izskatīties šādi:

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

Pēc noklusējuma izmaiņas no atlicināšanas kļūs pakāpeniskas. Ja vēlaties tos atcelt no skatuves, izmantojiet komandu git restore --staged(ja izmantojat Git jaunāku par 2.25.0).

Jūs vienkārši vēlaties lejupielādēt attālās izmaiņas

Pēdējais scenārijs nedaudz atšķiras no iepriekšējiem. Pieņemsim, ka jūs atrodaties ļoti netīras refaktorēšanas vidū. Ne zaudēt izmaiņas, ne arī nomaldīt tās nav iespējama. Tomēr jūs joprojām vēlaties, lai tālvadības izmaiņas būtu pieejamas, lai tās darbotos git diff.

Kā jūs droši vien esat sapratuši, tālvadības izmaiņu lejupielāde nemaz nav nepieciešama git pull! git fetchir tieši pietiekami.

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

Git pasaule ir plaša. Šis raksts aptvēra tikai vienu no krātuves uzturēšanas aspektiem: attālinātu izmaiņu iekļaušanu lokālajā krātuvē. Pat šis ikdienas scenārijs mums lika nedaudz padziļinātāk iepazīties ar šī versijas vadības rīka iekšējiem mehānismiem.

Apgūstot faktiskās lietošanas gadījumus, varat labāk saprast, kā Git darbojas zem pārsega. Tas savukārt liks jums justies pilnvarotiem ikreiz, kad nonākat nepatikšanās. Mēs visi laiku pa laikam to darām.