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
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?
-
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. -
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:
- Verwijder alle bestanden. Laat alleen de directory
.git
staan. git reset --hard HEAD
git pull
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 eengit 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.