Jak vynutit přepsání místních souborů v souboru git pull
?
Scénář je následující:
Toto je chyba, kterou dostávám:
error: Soubor neoznačených stromů 'public/images/icon.gif' by byl přepsán sloučením
Jak mohu Git přepsat? Osoba je designér - obvykle řeším všechny konflikty ručně, takže server má nejnovější verzi, kterou potřebuje pouze aktualizovat na svém počítači.
--hard
nebo bez ní budou ztraceny všechny místní příkazy, které nebyly posunuty.[*]Pokud máte nějaké soubory, které jsou ne sledovány Gitem (např. Nahraný obsah uživatele), nebudou tyto soubory ovlivněny.
Myslím, že je to správná cesta:
git fetch --all
Potom máte dvě možnosti:
git reset --hard Origin/master
NEBO Pokud jste na jiné pobočce:
git reset --hard Origin/<branch_name>
git fetch
stáhne nejnovější data ze vzdáleného počítače, aniž by se pokusil sloučit nebo znovu vytvořit cokoliv.
Pak git reset
resetuje hlavní větu na to, co jste právě načetli. Volba --hard
změní všechny soubory ve vašem pracovním stromu tak, aby odpovídaly souborům v souboru Origin/master
[*]: Stojí za zmínku, že je možné zachovat aktuální místní provize vytvořením větve z master
před resetováním:
git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard Origin/master
Poté budou všechny staré kompromisy uchovávány v new-branch-to-save-current-commits
.
Nezapomenuté změny, nicméně (i inscenované), budou ztraceny. Ujistěte se, že skrýš a spáchat cokoliv, co potřebujete. K tomu můžete spustit následující:
git stash
A pak znovu použít tyto nezávazné změny:
git stash pop
Zkuste to:
git reset --hard HEAD
git pull
Mělo by to, co chceš.
VAROVÁNÍ: git clean
vymaže všechny vaše nezaškrtnuté soubory/adresáře a nelze je vrátit zpět.
Někdy jen clean -f
nepomůže. V případě, že máte neprokázané DIRECTORIES, je potřeba také možnost -d:
# WARNING: this can't be undone!
git reset --hard HEAD
git clean -f -d
git pull
VAROVÁNÍ: git clean
vymaže všechny vaše nezaškrtnuté soubory/adresáře a nelze je vrátit zpět.
Zvažte nejprve -n
(--dry-run
) příznak. To vám ukáže, co bude smazáno, aniž byste cokoli smazali:
git clean -n -f -d
Příklad výstupu:
Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
Jako Hedgehog si myslím, že odpovědi jsou hrozné. Ale i když Hedgehogova odpověď může být lepší, nemyslím si, že je tak elegantní, jak by mohla být. Způsob, jakým jsem to zjistil, je pomocí "načíst" a "sloučit" s definovanou strategií. Který by měl dělat to tak, aby vaše lokální změny zůstaly zachovány, pokud nejsou jedním ze souborů, které se pokoušíte přepsat.
git add *
git commit -a -m "local file server commit message"
git fetch Origin master
git merge -s recursive -X theirs Origin/master
"-X" je název volby a "jejich" je hodnota této volby. Rozhodnete se použít "své" změny namísto "vašich" změn v případě konfliktu.
Místo toho:
git fetch --all
git reset --hard Origin/master
Doporučil bych následující:
git fetch Origin master
git reset --hard Origin/master
Není třeba načíst všechny dálkové ovladače a větve, pokud budete chtít obnovit původní/hlavní pobočku?
Vypadá to, že nejlepší způsob je nejprve:
git clean
Chcete-li odstranit všechny nesledované soubory a poté pokračovat obvyklým git pull
...
Některé odpovědi se zdají být hrozné. Hrozný ve smyslu toho, co se stalo @Lauri následováním Davida Avsajanishviliho návrhu.
Spíše (git> v1.7.6):
git stash --include-untracked
git pull
Později můžete ukrýt historii skrýš.
Ručně, po jednom:
$ git stash list
[email protected]{0}: WIP on <branch>: ...
[email protected]{1}: WIP on <branch>: ...
$ git stash drop [email protected]{0}
$ git stash drop [email protected]{1}
Brutálně, najednou:
$ git stash clear
Samozřejmě, pokud se chcete vrátit zpět k tomu, co jste ukryli:
$ git stash list
...
$ git stash apply [email protected]{5}
Tento příkaz vám může pomoci odstranit místní změny:
git checkout <your-branch> -f
A pak proveďte vyčištění (odstraní nesledované soubory z pracovního stromu):
git clean -f
Chcete-li kromě neoznačených souborů odebrat nesledované adresáře:
git clean -fd
Namísto sloučení s git pull
zkuste toto:
git fetch --all
následován:
git reset --hard Origin/master
.
Jediné, co pro mě fungovalo, bylo:
git reset --hard HEAD~5
To vám vrátí pět provizí a pak s
git pull
Zjistil jsem, že vzhlédl jak vrátit Git merge .
Problém se všemi těmito řešeními spočívá v tom, že jsou buď příliš složité, nebo ještě větší problém spočívá v tom, že odstraňují všechny nesledované soubory z webového serveru, které nechceme, protože jsou vždy potřebné konfigurační soubory, které jsou zapnuty. serveru a nikoli v repozitáři Git.
Zde je nejčistší řešení, které používáme:
# 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
První příkaz vyvolá nejnovější data.
Druhý příkaz zkontroluje, zda existují nějaké soubory, které jsou přidány do úložiště, a odstraní tyto nepozorované soubory z lokálního úložiště, což by způsobilo konflikty.
Třetí příkaz kontroluje všechny soubory, které byly lokálně upraveny.
Nakonec se pokusíme aktualizovat na nejnovější verzi, ale tentokrát bez jakýchkoli konfliktů, protože nepozorované soubory, které jsou v repo již neexistují, a všechny lokálně upravené soubory jsou již stejné jako v úložišti.
Měl jsem stejný problém. Nikdo mi toto řešení nedal, ale fungovalo to pro mě.
Vyřešil jsem to:
.git
adresář.git reset --hard HEAD
git pull
git Push
Teď to funguje.
Nejprve vyzkoušejte standardní způsob:
git reset HEAD --hard # To remove all not committed changes!
git clean -fd # To remove all untracked (non-git) files and folders!
Varování : Výše uvedené příkazy mohou mít za následek ztrátu dat/souborů pouze v případě, že je nezadáte! Pokud si nejste jisti, proveďte zálohu nejprve z celé složky úložiště.
Pak ji znovu vytáhněte.
Pokud vám to nepomůže a nezajímá vás vaše nezaškrtnuté soubory/adresáře (proveďte zálohování nejdříve jen v případě), zkuste následující jednoduché kroky:
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
Tím odstraníte všechny soubory git (výjimka .git/
dir, kde máte všechny závazky) a znovu ji vytáhněte.
Proč by git reset HEAD --hard
mohlo v některých případech selhat?
Vlastní pravidla v souboru .gitattributes file
Pravidlo eol=lf
v .gitattributes by mohlo způsobit, že git změní některé změny souborů převedením řádků CRLF do LF v některých textových souborech.
Pokud tomu tak je, musíte tyto změny CRLF/LF spáchat (jejich přezkoumáním v souboru git status
) nebo zkusit: git config core.autcrlf false
dočasně je ignorovat.
Neschopnost souborového systému
Když používáte systém souborů, který nepodporuje atributy oprávnění V příkladu máte dva repozitáře, jeden na Linux/Mac (ext3
/hfs+
) a druhý na souborovém systému založeném na FAT32/NTFS.
Jak si všimnete, existují dva různé druhy souborových systémů, takže ten, který nepodporuje unixová oprávnění, v podstatě nemůže obnovit oprávnění k souborům v systému, který nepodporuje tento druh oprávnění, takže bez ohledu na to, jak --hard
zkusíte, git vždy detekuje nějaké "změny".
Když hovořím o tahu/vyzvednutí/sloučení v předchozích odpovědích, rád bych se podělil o zajímavý a produktivní trik,
git pull --rebase
Tento výše uvedený příkaz je nejužitečnějším příkazem v mém životě Git, který ušetřil spoustu času.
Než začnete tisknout svůj nový závazek na server, zkuste tento příkaz a bude automaticky synchronizovat nejnovější změny serveru (s aplikací fetch + merge) a umístí vaše potvrzení v horní části protokolu Git. Není třeba se starat o ruční tažení/sloučení.
Podrobnosti naleznete v Co znamená "git pull --rebase" do?.
Měl jsem podobný problém. Musel jsem to udělat:
git reset --hard HEAD
git clean -f
git pull
Shrnula jsem další odpovědi. git pull
můžete provést bez chyb:
git fetch --all
git reset --hard Origin/master
git reset --hard HEAD
git clean -f -d
git pull
Varování : Tento skript je velmi silný, takže můžete ztratit své změny.
Na základě mých vlastních podobných zkušeností je řešení, které nabízí Strahinja Kustudic výše, zdaleka nejlepší. Jak jiní zdůraznili, jednoduše provedením tvrdého resetu odstraníte všechny nesledované soubory, které by mohly obsahovat spoustu věcí, které nechcete odstranit, například konfigurační soubory. Bezpečnější je odebrat pouze soubory, které mají být přidány, a za tímto účelem byste pravděpodobně chtěli také vyzkoušet všechny místně upravené soubory, které mají být aktualizovány.
To jsem si uvědomil, aktualizoval jsem Kustudicův scénář, aby to udělal. Také jsem opravil překlep (chybějící) v originálu).
#/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
Věřím, že existují dvě možné příčiny konfliktu, které musí být řešeny odděleně, a pokud nemohu říci, že žádná z výše uvedených odpovědí se nezabývá:
Lokální soubory, které jsou nezaškrtnuté, je třeba smazat, buď ručně (bezpečněji) nebo podle jiných odpovědí, podle git clean -f -d
Místní příkazy, které nejsou ve vzdálené větvi, je třeba také vymazat. IMO nejjednodušší způsob, jak toho dosáhnout, je: git reset --hard Origin/master
(nahraďte výraz „master“ libovolnou větví, na kterém pracujete, a nejprve spusťte soubor git fetch Origin
)
Snadnější by bylo:
git checkout --theirs /path/to/file.extension
git pull Origin master
To přepíše váš lokální soubor se souborem na git
Zdá se, že většina odpovědí je zaměřena na větev master
; nicméně, tam jsou časy, kdy pracuji na stejné rys pobočky na dvou různých místech a chci rebase v jednom se odráží v ostatních, aniž by hodně skákání přes obruče.
Na základě kombinace odpovědí RNA a torekovy odpovědi na podobnou otázku jsem přišel s tím, co funguje skvěle:
git fetch
git reset --hard @{u}
Spusťte to z větve a obnoví pouze lokální pobočku na vyšší verzi.
To může být také pěkně vloženo do alias git (git forcepull
):
git config alias.forcepull "!git fetch ; git reset --hard @{u}"
Nebo v souboru .gitconfig
:
[alias]
forcepull = "!git fetch ; git reset --hard @{u}"
Užívat si!
Měl jsem stejný problém a z nějakého důvodu, ani git clean -f -d
by to neudělal. Zde je důvod, proč: Z nějakého důvodu, pokud váš soubor je ignorován Git (přes vstup .gitignore, předpokládám, že), to stále vadí o přepsání to později pull , ale clean nebude odstranit, pokud nezadáte -x
.
Já jsem to vyřešil sám:
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
kde poslední příkaz uvádí seznam místních změn. Upravte větev "tmp" tak, aby byla přijatelná a poté sloučena zpět na hlavní server pomocí:
git checkout master && git merge tmp
Pro příště, můžete pravděpodobně zvládnout to v čistším způsobem tím, že hledá "git stash větev" i když skrýt je pravděpodobné, že vám způsobí potíže v prvních několika pokusů, takže se první experiment na nekritické projektu ...
Mám zvláštní situaci, že ani git clean
ani git reset
nefunguje. Musím odstranit konfliktní soubor z git index
pomocí následujícího skriptu v každém nezaškrtnutém souboru:
git rm [file]
Pak jsem schopen vytáhnout v pohodě.
Vím o mnohem jednodušší a méně bolestivé metodě:
$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp
A je to!
Tyto čtyři příkazy pracují pro mě.
git reset --hard HEAD
git checkout Origin/master
git branch -D master
git checkout -b master
Chcete-li zkontrolovat/vytáhnout po provedení těchto příkazů
git pull Origin master
Zkoušel jsem hodně, ale nakonec jsem s těmito povely dosáhl úspěchu.
Prostě
git fetch Origin branchname
git checkout -f Origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge Origin/branchname
Vyhnete se tak veškerým nežádoucím vedlejším účinkům, například vymazání souborů nebo adresářů, které chcete zachovat, atd.
Navzdory původní otázce mohou hlavní odpovědi způsobit problémy lidem, kteří mají podobný problém, ale nechtějí ztratit své místní soubory. Viz například komentáře Al-Punk a crizCraig.
Následující verze zavádí místní změny do dočasné větve (tmp
), kontroluje původní větev (která je předpokladem master
) a sloučí aktualizace. Můžete to udělat s stash
, ale zjistil jsem, že je obvykle jednodušší použít přístup větev/sloučení.
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
kde předpokládáme další repozitář je Origin master
.
Obnovte index a hlavu na Origin/master
, ale pracovní strom nulovat:
git reset Origin/master
Požadavky:
Řešení:
Načíst s clean z souborů a adresářů ignorovat .gitignore a hard reset na Původ .
git stash --include-untracked
git fetch --all
git clean -fdx
git reset --hard Origin/master
Četl jsem všechny odpovědi, ale hledal jsem jediný příkaz, jak to udělat. Tady je to, co jsem udělal. Přidán alias git .gitconfig
[alias]
fp = "!f(){ git fetch ${1} ${2} && git reset --hard ${1}/${2};};f"
Spusťte příkaz jako
git fp Origin master
ekvivalentní
git fetch Origin master
git reset --hard Origin/master
Nepoužívejte git reset --hard
. To zničí jejich změny, které mohou být zcela nežádoucí. Místo toho:
git pull
git reset Origin/master
git checkout <file1> <file2> ...
Můžete samozřejmě použít git fetch
místo git pull
, protože to zjevně nebude sloučit, ale pokud obvykle taháte, má smysl pokračovat v tahání zde.
Takže co se stane, je to, že git pull
aktualizuje vaši Origin/master referenci; git reset
aktualizuje odkaz na místní pobočku na to, aby byl stejný jako Origin/master, aniž by byly aktualizovány všechny soubory, takže váš stav odhlášení je beze změny; pak git checkout
podle potřeby vrátí soubory do stavu lokálního indexu pobočky. V případech, kdy byl přidán přesně stejný soubor na živý a na předřazený master, index již odpovídá souboru po resetu, takže v běžném případě nemusíte vůbec dělat git checkout
vůbec.
Pokud předřazená větev obsahuje také provize, které chcete použít automaticky, můžete postupovat podle jemné odchylky v procesu:
git pull
git merge <commit before problem commit>
git reset <problem commit>
git checkout <file1> <file2> ...
git pull
Toto je nejlepší postup pro vrácení změn:
git commit
Potvrďte provedené změny, aby byly uloženy do souboru reflog (viz níže)git fetch
Načte poslední změny upstreamgit reset --hard Origin/master
Pevný reset na pobočku Origin masterreflogzáznamy poboček a dalších odkazů jsou aktualizovány v lokálním úložišti. Nebo jednoduše - reflog je historie vašich změn.
Je to vždycky skvělá praxe. Commits jsou připojeny k reflogu, který zajišťuje, že budete mít vždy způsob, jak načíst smazaný kód.
Použil jsem tento příkaz, abych se zbavil místních souborů, které mi brání v tahu/sloučení. Ale buď opatrný! Nejprve spusťte git merge …
a zjistěte, zda existují pouze ty soubory, které chcete opravdu odstranit.
git merge Origin/master 2>&1 >/dev/null | grep ^[[:space:]] | sed s/^[[:space:]]//g | xargs -L1 rm
git merge
mimo jiné uvádí všechny tyto soubory. Jsou předpřipraveny nějakým bílým prostorem.2>&1 >/dev/null
přesměruje chybový výstup na standardní, takže je grep
.grep ^[[:space:]]
filtruje pouze řádky s názvy souborů.sed s/^[[:space:]]//g
ořízne bílou mezeru od začátku.xargs -L1 rm
volání rm
na každém z těchto souborů, jejich smazání.Zacházejte s péčí opatrně: git merge
výstupy, rm
bude voláno pro každý řádek začínající bílým mezerou.
Snažil jsem se použít větev Material2 na Angular2-Webpack-Starter a měl jsem sakra času. To byla jediná možnost, jak tuto pobočku stáhnout a použít.
git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git
cd angular2-webpack-starter/
git checkout -b material2
Otevřete složku projektu a odstraňte všechny skryté soubory a složky. Nechte všechny skryté.
git add .
git commit -m "pokemon go"
git reset --hard
git pull Origin material2
(Když se editor objeví, stiskněte ': wq' a pak stiskněte Enter)
Nyní jste připraveni.
V systému Windows proveďte tento jediný příkaz:
git fetch --all & git reset --hard Origin/master
Tento soubor můžete ignorovat se souborem v základní složce projektu:
.gitignore
public/images/*
Pak tyto změny vytáhněte a pak odstraňte tento řádek ze souboru gitignore.
git fetch --all && git reset --hard Origin/master && git pull
1: Obnovení předchozího potvrzení
git reset --hard HEAD
2: Smazat neskenované soubory
git clean -f
3: Vytáhněte provize
git pull
Prameny:
chcete-li resetovat pobočku vzdáleného sledování obecným způsobem, použijte:
git fetch
git reset --keep Origin/$(git rev-parse --abbrev-ref HEAD)
chcete-li také obnovit místní změny:
git fetch
git reset --hard Origin/$(git rev-parse --abbrev-ref HEAD)