it-swarm-eu.dev

Jak vynutit "git pull" přepsat místní soubory?

Jak vynutit přepsání místních souborů v souboru git pull?

Scénář je následující:

  • Člen týmu upravuje šablony pro web, na kterém pracujeme
  • Přidávají některé obrázky do adresáře obrázků (ale zapomněli je přidat pod kontrolu zdroje)
  • Obrázky posílají poštou, později mi
  • Přidávám obrázky pod kontrolou zdroje a posouvám je do GitHubu spolu s dalšími změnami
  • Nemohou stahovat aktualizace z GitHubu, protože Git nechce přepsat své soubory.

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.

5771
Jakub Troszok

Důležité: Pokud máte nějaké místní změny, budou ztraceny. S volbou --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>

Vysvětlení:

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


Zachovat aktuální místní závazky

[*]: 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

Nezávazné změny

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
8139
RNA

Zkuste to:

git reset --hard HEAD
git pull

Mělo by to, co chceš.

808
Travis Reeder

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
...
409

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. 

Nejprve proveďte změny svých změn

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

Pak proveďte změny a přepište, pokud dojde ke konfliktu

 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.

347
Richard Kersey

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?

251
Johanneke

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...

125
Jakub Troszok

Varování, toto bude trvale odstraňovat vaše soubory, pokud máte ve vašem souboru gitignore nějaké položky adresáře/*.

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}
102
Hedgehog

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
88
Vishal

Namísto sloučení s git pull zkuste toto: 

git fetch --all

následován:

git reset --hard Origin/master.

82
Lloyd Moore

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 .

55
Chris BIllante

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.

51

Měl jsem stejný problém. Nikdo mi toto řešení nedal, ale fungovalo to pro mě.

Vyřešil jsem to:

  1. Odstraňte všechny soubory. Nechte jen .git adresář.
  2. git reset --hard HEAD
  3. git pull
  4. git Push

Teď to funguje.

39

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?

  1. 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.

  2. 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".

34
kenorb

Bonus:

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?.

33

Měl jsem podobný problém. Musel jsem to udělat:

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

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.

27
Robert Moon

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
26
Rolf Kaiser

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)

23
tiho

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

20
maximus 69

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!

20
JacobEvelyn

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.

19
Tierlieb

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 ...

18
Simon B.

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ě.

17
Chen Zhang

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!

16
ddmytrenko

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.

13
vishesh chandra

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.

12
user2696128

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.

12
Snowcrash

Obnovte index a hlavu na Origin/master, ale pracovní strom nulovat:

git reset Origin/master
11
user811773

Požadavky:

  1. Sledujte místní změny, aby je nikdo nikdy neztratil.
  2. Zajistěte, aby lokální úložiště odpovídalo vzdálenému úložišti Origin.

Řešení:

  1. Stash místní změny.
  2. 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
    
9
vezenkov

Č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
9
Venkat Kotra

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 pullaktualizuje vaši Origin/master referenci; git resetaktualizuje 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 checkoutpodle 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
8
Jim Driscoll

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 upstream
  • git reset --hard Origin/master Pevný reset na pobočku Origin master

reflogzá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.

7
Jordan Georgiev

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.

5
Glutexo

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.

5
Helzgate

V systému Windows proveďte tento jediný příkaz:

git fetch --all & git reset --hard Origin/master
3
Luca C.

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.

3
Daniel Gaytán

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

0
Suge

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:

0
abhijithvijayan

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)
0
warch