Hoe forceer ik “git pull” om lokale bestanden te overschrijven?

Hoe forceer ik een overschrijving van lokale bestanden op een git pull?

Het scenario is het volgende:

  • Een teamlid past de sjablonen aan voor een website waaraan we werken
  • Ze voegen enkele afbeeldingen toe aan de afbeeldingenmap (maar vergeten ze toe te voegen onder bronbeheer)
  • Ze sturen de afbeeldingen later per post naar mij
  • Ik voeg de afbeeldingen toe onder het bronbeheer en push ze naar GitHub samen met andere wijzigingen
  • Ze kunnen geen updates van GitHub halen omdat Git hun bestanden niet wil overschrijven.

Dit is de foutmelding die ik krijg:

fout: niet-bijgehouden werkboombestand ‘public/images/icon.gif’ zou worden overschreven door samenvoegen

Hoe dwing ik Git om ze te overschrijven? De persoon is een ontwerper – meestal los ik alle conflicten met de hand op, dus de server heeft de meest recente versie die ze alleen op hun computer hoeven te updaten.


Antwoord 1, autoriteit 100%

? Belangrijk: Als u lokale wijzigingen heeft, gaan deze verloren. Met of zonder --hard optie, zullen lokale commits die niet gepusht zijn verloren gaan.[*]

Als je bestanden hebt die niet worden bijgehouden door Git (bijv. geüploade gebruikersinhoud), worden deze bestanden niet beïnvloed.


Voer eerst een fetch uit om alle origin/<branch>-referen bij te werken naar de nieuwste:

git fetch --all

Maak een back-up van uw huidige branch:

git branch backup-master

Dan heb je twee opties:

git reset --hard origin/master

OF Als je op een andere tak zit:

git reset --hard origin/<branch_name>

Uitleg:

git fetch downloadt het laatste nieuws van op afstand zonder te proberen iets samen te voegen of te rebasen.

Dan zet de git reset de master branch terug naar wat je zojuist hebt opgehaald. De optie --hard verandert alle bestanden in uw werkboom zodat ze overeenkomen met de bestanden in origin/master


Behoud huidige lokale verplichtingen

[*]: het is vermeldenswaard dat het mogelijk is om de huidige lokale commits te behouden door een branch te maken van master voordat je reset:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

Hierna worden alle oude commits bewaard in new-branch-to-save-current-commits.

Niet-vastgelegde wijzigingen

Niet-vastgelegde wijzigingen (zelfs gefaseerd) gaan echter verloren. Zorg ervoor dat je alles wat je nodig hebt opbergt en vastlegt. Daarvoor kun je het volgende uitvoeren:

git stash

En dan om deze niet-vastgelegde wijzigingen opnieuw toe te passen:

git stash pop

Antwoord 2, autoriteit 9%

Probeer dit:

git reset --hard HEAD
git pull

Het zou moeten doen wat je wilt.


Antwoord 3, autoriteit 4%

WAARSCHUWING: git clean verwijdert al uw niet-getrackte bestanden/mappen en kan niet ongedaan worden gemaakt.


Soms helpt alleen clean -f niet. Als je niet-getrackte DIRECTORIES hebt, heb je ook de optie -d nodig:

# WARNING: this can't be undone!
git reset --hard HEAD
git clean -f -d
git pull

WAARSCHUWING: git clean verwijdert al uw niet-getrackte bestanden/mappen en kan niet ongedaan worden gemaakt.

Overweeg om eerst de vlag -n (--dry-run) te gebruiken. Dit zal u laten zien wat er zal worden verwijderd zonder daadwerkelijk iets te verwijderen:

git clean -n -f -d

Voorbeelduitvoer:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...

Antwoord 4, autoriteit 4%

Net als Hedgehog vind ik de antwoorden verschrikkelijk. Maar hoewel het antwoord van Hedgehog misschien beter is, denk ik niet dat het zo elegant is als het zou kunnen zijn. De manier waarop ik dit heb kunnen doen, is door fetch en merge te gebruiken met een gedefinieerde strategie. Dat zou ervoor moeten zorgen dat uw lokale wijzigingen behouden blijven zolang ze niet een van de bestanden zijn waarmee u een overschrijving probeert te forceren.

Doe eerst een vastlegging van uw wijzigingen

 git add *
 git commit -a -m "local file server commit message"

Vervolgens de wijzigingen ophalen en overschrijven als er een conflict is

 git fetch origin master
 git merge -s recursive -X theirs origin/master

-x is een optienaam en theirs is de waarde voor die optie. Je kiest ervoor om their wijzigingen te gebruiken (de andere optie is ours wijzigingen) als er een conflict is.


Antwoord 5, autoriteit 3%

In plaats van te doen:

git fetch --all
git reset --hard origin/master

Ik raad u aan het volgende te doen:

git fetch origin master
git reset --hard origin/master

Het is niet nodig om alle remotes en branches op te halen als je gaat resetten naar de origin/master branch, toch?


Antwoord 6

Het lijkt erop dat de beste manier is om eerst het volgende te doen:

git clean

Om alle niet-getrackte bestanden te verwijderen en dan verder te gaan met de gebruikelijke git pull


Antwoord 7

Waarschuwing, Als u dit doet, worden uw bestanden permanent verwijderd als u directory/*-items in uw gitignore-bestand heeft.

Sommige antwoorden lijken verschrikkelijk. Verschrikkelijk in de zin van wat er met @Lauri is gebeurd door de suggestie van David Avsajanishvili op te volgen.

In plaats van (git > v1.7.6):

git stash --include-untracked
git pull

Later kunt u de stashgeschiedenis opschonen.

Handmatig, één voor één:

$ git stash list
stash@{0}: WIP on <branch>: ...
stash@{1}: WIP on <branch>: ...
$ git stash drop stash@{0}
$ git stash drop stash@{1}

Ineens brutaal:

$ git stash clear

Natuurlijk als je terug wilt naar wat je hebt opgeslagen:

$ git stash list
...
$ git stash apply stash@{5}

Antwoord 8

Misschien vindt u deze opdracht nuttig om lokale wijzigingen weg te gooien:

git checkout <your-branch> -f

En doe dan een opschoning (verwijdert niet-getrackte bestanden uit de werkboom):

git clean -f

Als u niet-getrackte mappen wilt verwijderen naast niet-getrackte bestanden:

git clean -fd

Antwoord 9

Probeer dit in plaats van samen te voegen met git pull:

git fetch --all

gevolgd door:

git reset --hard origin/master.


Antwoord 10

Het enige dat voor mij werkte was:

git reset --hard HEAD~5

Hiermee krijg je vijf commits terug en dan met

git pull

Ik ontdekte dat door hoe een Git-samenvoeging ongedaan te maken op te zoeken.


Antwoord 11

Het probleem met al deze oplossingen is dat ze allemaal ofwel te complex zijn, of, een nog groter probleem, is dat ze alle niet-getrackte bestanden van de webserver verwijderen, wat we niet willen omdat er altijd configuratiebestanden nodig zijn die op de server staan ​​en niet in de Git-repository.

Dit is de schoonste oplossing die we gebruiken:

# Fetch the newest code
git fetch
# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done
# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done
# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • De eerste opdracht haalt de nieuwste gegevens op.

  • Het tweede commando controleert of er bestanden zijn die aan de repository worden toegevoegd en verwijdert die niet-getrackte bestanden uit de lokale repository die conflicten zouden veroorzaken.

  • De derde opdracht controleert alle bestanden die lokaal zijn gewijzigd.

  • Eindelijk doen we een pull om te updaten naar de nieuwste versie, maar deze keer zonder conflicten, omdat niet-getrackte bestanden die in de repo staan ​​niet meer bestaan ​​en alle lokaal gewijzigde bestanden al hetzelfde zijn als in de repository.


Antwoord 12

Probeer eerst de standaardmanier:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

Waarschuwing: bovenstaande commando’s kunnen alleen leiden tot verlies van gegevens/bestanden als u ze niet hebt vastgelegd! Als je het niet zeker weet, maak dan eerst de back-up van je hele repositorymap.

Trek er dan nog een keer aan.

Als bovenstaande niet helpt en je niet geïnteresseerd bent in je niet-getrackte bestanden/mappen (maak eerst de back-up voor het geval dat), probeer dan de volgende eenvoudige stappen:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

Dit zal alle git-bestanden VERWIJDEREN (behalve .git/ dir, waar je alle commits hebt) en het opnieuw ophalen.


Waarom kan git reset HEAD --hard in sommige gevallen mislukken?

  1. Aangepaste regels in .gitattributes file

    Het hebben van een eol=lf regel in .gitattributes kan ertoe leiden dat git sommige bestandswijzigingen aanpast door CRLF regeleinden te converteren naar LF in sommige tekstbestanden.

    Als dat het geval is, moet je deze CRLF/LF-wijzigingen vastleggen (door ze te bekijken in git status), of probeer: git config core.autcrlf false om ze tijdelijk te negeren.

  2. Incompatibiliteit met bestandssysteem

    Als je een bestandssysteem gebruikt dat geen toestemmingsattributen ondersteunt.
    Je hebt bijvoorbeeld twee repositories, een op Linux/Mac (ext3/hfs+) en een andere op een op FAT32/NTFS gebaseerd bestandssysteem.

    Zoals je opmerkt, zijn er twee verschillende soorten bestandssystemen, dus degene die geen Unix-machtigingen ondersteunt, kan in principe geen bestandsmachtigingen opnieuw instellen op een systeem dat dat soort machtigingen niet ondersteunt, dus het maakt niet uit hoe --hard je probeert, git detecteert altijd enkele “veranderingen”.


Antwoord 13

Ik had hetzelfde probleem. Niemand gaf me deze oplossing, maar het werkte voor mij.

Ik heb het opgelost door:

  1. Verwijder alle bestanden. Laat alleen de directory .git staan.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Nu werkt het.


Antwoord 14

Bonus:

Als we het hebben over pull/fetch/merge in de vorige antwoorden, zou ik graag een interessante en productieve truc willen delen,

git pull --rebase

Dit bovenstaande commando is het meest bruikbare commando in mijn Git-leven dat veel tijd heeft bespaard.

Voordat je je nieuwe commit naar de server pusht, probeer deze opdracht en het zal automatisch de laatste serverwijzigingen synchroniseren (met een fetch + merge) en je commit bovenaan in het Git-logboek plaatsen. U hoeft zich geen zorgen te maken over handmatig ophalen/samenvoegen.

Vind details in Wat doet "git pull –rebase" doen?.


Antwoord 15

Ik had een soortgelijk probleem. Ik moest dit doen:

git reset --hard HEAD
git clean -f
git pull

Antwoord 16

Ik heb andere antwoorden samengevat. Je kunt git pull zonder fouten uitvoeren:

git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

Waarschuwing: dit script is erg krachtig, dus u kunt uw wijzigingen kwijtraken.


Antwoord 17

Op basis van mijn eigen soortgelijke ervaringen is de oplossing die Strahinja Kustudic hierboven biedt verreweg de beste. Zoals anderen al hebben opgemerkt, verwijdert u door simpelweg een harde reset uit te voeren alle bestanden die niet zijn bijgehouden, waaronder veel dingen die u niet wilt laten verwijderen, zoals configuratiebestanden. Wat veiliger is, is om alleen de bestanden te verwijderen die op het punt staan ​​te worden toegevoegd, en wat dat betreft wil je waarschijnlijk ook alle lokaal gewijzigde bestanden die op het punt staan ​​te worden bijgewerkt, uitchecken.

Daarom heb ik Kustudic’s script geüpdatet om precies dat te doen. Ik heb ook een typfout gecorrigeerd (een ontbrekende ‘ in het origineel).

#/bin/sh
# Fetch the newest code
git fetch
# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done
# Checkout all files which have been locally modified
for file in `git diff HEAD..origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done
# Finally merge all the changes (you could use merge here as well)
git pull

Antwoord 18

Ik geloof dat er twee mogelijke oorzaken van conflicten zijn, die afzonderlijk moeten worden opgelost, en voor zover ik weet heeft geen van de bovenstaande antwoorden betrekking op beide:

  • Lokale bestanden die niet zijn getraceerd, moeten worden verwijderd, hetzij handmatig (veiliger) of zoals gesuggereerd in andere antwoorden, door git clean -f -d

  • Lokale commits die niet op de remote branch staan, moeten ook verwijderd worden. IMO de gemakkelijkste manier om dit te bereiken is met: git reset --hard origin/master (vervang ‘master’ door de branch waaraan je werkt, en voer een git fetch origin eerst)


Antwoord 19

git fetch --all && git reset --hard origin/master && git pull


Antwoord 20

Het lijkt erop dat de meeste antwoorden hier gericht zijn op de master branch; er zijn echter momenten dat ik op twee verschillende plaatsen aan dezelfde feature-branch werk en ik wil dat een rebase in de ene wordt weerspiegeld in de andere zonder veel door hoepels te springen.

Gebaseerd op een combinatie van RNA’s antwoord en Toreks antwoord op een soortgelijke vraag, ik heb dit bedacht dat uitstekend werkt:

git fetch
git reset --hard @{u}

Voer dit uit vanuit een branch en het zal alleen je lokale branch resetten naar de upstream-versie.

Dit kan ook mooi in een git-alias (git forcepull) worden gezet:

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

Of, in je .gitconfig bestand:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Veel plezier!


Antwoord 21

Ik had hetzelfde probleem en om de een of andere reden zou zelfs een git clean -f -d het niet doen. Dit is de reden waarom: om de een of andere reden, als je bestand door Git wordt genegeerd (via een .gitignore-item, neem ik aan), het nog steeds de moeite neemt dit te overschrijven met een latere pull, maar een schone zal het niet verwijderen, tenzij je -x toevoegt.


Antwoord 22

Een gemakkelijkere manier zou zijn om:

git checkout --theirs /path/to/file.extension
git pull origin master

Dit zal je lokale bestand overschrijven met het bestand op git


Antwoord 23

Ik ken een veel gemakkelijkere en minder pijnlijke methode:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

Dat is het!


Antwoord 24

Ik heb dit zojuist zelf opgelost door:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

waarbij het laatste commando een lijst geeft van wat uw lokale wijzigingen waren. Blijf de “tmp” branch aanpassen totdat het acceptabel is en merge dan terug naar master met:

git checkout master && git merge tmp

Voor de volgende keer kun je dit waarschijnlijk op een schonere manier aanpakken door “git stash branch” op te zoeken, hoewel stash je waarschijnlijk problemen geeft bij de eerste paar pogingen, dus experimenteer eerst op een niet-kritiek project.. .


Antwoord 25

Ik heb een vreemde situatie dat noch git clean of git reset werkt. Ik moet het conflicterende bestand uit git index verwijderen door het volgende script te gebruiken op elk niet-gevolgd bestand:

git rm [file]

Dan kan ik prima trekken.


Antwoord 26

Gebruik:

git fetch --all

Als je dan in de master branch zit,

git reset --hard origin/master

anders

git reset --hard origin/master<branch_name>

Antwoord 27

Gewoon doen

git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname

Zo vermijd je alle ongewenste neveneffecten, zoals het verwijderen van bestanden of mappen die je wilde behouden, enz.


Antwoord 28

Ondanks de oorspronkelijke vraag kunnen de beste antwoorden problemen veroorzaken voor mensen die een soortgelijk probleem hebben, maar hun lokale bestanden niet willen verliezen. Zie bijvoorbeeld de opmerkingen van Al-Punk en crizCraig.

De volgende versie legt je lokale wijzigingen vast in een tijdelijke branch (tmp), checkt de originele branch uit (waarvan ik aanneem dat het master is) en voegt de updates samen . Je zou dit kunnen doen met stash, maar ik heb gemerkt dat het meestal gemakkelijker is om simpelweg de branch / merge-aanpak te gebruiken.

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master
git fetch origin master
git merge -s recursive -X theirs origin master

waarbij we aannemen dat de andere repository origin master is.


Antwoord 29

Reset de index en de kop naar origin/master, maar reset de werkboom niet:

git reset origin/master

Antwoord 30

Deze vier commando’s werken voor mij.

git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

Controleren/trekken na het uitvoeren van deze commando’s

git pull origin master

Ik heb veel geprobeerd, maar kreeg uiteindelijk succes met deze commando’s.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

five × 5 =

Other episodes