Chvíľu som náhodou pracoval na vetve, na ktorej som nemal, a tak som sa z nej oddelil a dal jej príslušný názov. Teraz chcem prepísať vetvu, na ktorej som nemal byť, na verziu z originu (github). Existuje nejaký jednoduchý spôsob, ako to urobiť? Skúšal som vetvu vymazať a potom obnoviť sledovanie vetvy, ale to mi opäť dáva len verziu, na ktorej som pracoval.
Ak ste ešte nepostúpili do origin, môžete svoju vetvu resetovať na vetvu upstream pomocou:
git checkout mybranch
git reset --hard origin/mybranch
(Uistite sa, že odkazujete na svoju poslednú revíziu v samostatnej vetve, ako uvádzate vo svojej otázke)
Všimnite si, že hneď po resetovaní mybranch@{1}
odkazuje na starú revíziu pred resetovaním.
Ak ste však už vykonali push, pozrite si "Create git branch, and revert original to upstream state" pre ďalšie možnosti.
V systéme Git 2.23 (august 2019) by to bol jeden príkaz: git switch
.
Konkrétne: git switch -C mybranch origin/mybranch
.
Príklad
C:\Users\vonc\git\git>git switch -C master origin/master
Reset branch 'master'
Branch 'master' set up to track remote branch 'master' from 'origin'.
Your branch is up to date with 'origin/master'.
Tým sa obnoví index a pracovný strom, podobne ako by to urobil git reset --hard
.
Ako komentoval Brad Herman, reset --hard
by odstránil každý nový súbor alebo obnovil zmenený súbor na HEAD.
V skutočnosti, aby ste si boli istí, že začínate od "čistého štítu", git clean -f -d
po resete by zabezpečil pracovný strom presne identický s vetvou, na ktorú ste práve resetovali.
Tento blogový príspevok navrhuje tieto aliasy (len pre vetvu master
, ale môžete si ich prispôsobiť/rozšíriť):
[alias] resetorigin = !git fetch origin && git reset --hard origin/master && git clean -f -d resetupstream = !git fetch upstream && git reset --hard upstream/master && git clean -f -d
Potom môžete zadať:
git resetupstream
alebo
git resetorigin
Predpokladajme, že sa to stalo:
# on branch master
vi buggy.py # you edit file
git add buggy.py # stage file
git commit -m "Fix the bug" # commit
vi tests.py # edit another file but do not commit yet
Potom si uvedomíte, že ste vykonali zmeny v nesprávnej vetve.
git checkout -b mybranch # you create the correct branch and switch to it
Ale master
stále ukazuje na vašu revíziu. Chcete, aby ukazoval tam, kam ukazoval predtým.
Najjednoduchší spôsob je:
git branch --force master origin/master
Ďalší spôsob je:
git checkout master
git reset --soft origin/master
git checkout mybranch
Všimnite si, že použitie reset --hard
spôsobí stratu vašich neodovzdaných zmien (tests.py
v mojom príklade).
Mám súkromné repozitáre na serveri a pravidelne do nich rebazujem/vynucujem, čo spôsobuje, že musím často resetovať lokálnu vetvu na svojom druhom počítači. Preto som vytvoril nasledujúci alias "catchup", ktorý to umožňuje pre aktuálnu vetvu. Na rozdiel od inej odpovede nie je v tomto aliase natvrdo zakódovaný názov vetvy.
Držte sa pevne.
[alias]
catchup = "!f(){ echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \"; read -r ans; if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)); else echo \"catchup aborted\"; fi }; f"
Správne naformátované (nebude to fungovať s novými riadkami v .gitconfig) to vyzerá takto:
"
!f(){
echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \";
read -r ans;
if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then
git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD));
else
echo \"catchup aborted\";
fi
}; f
"
\\033[0;33m
a \\033[0m
slúžia na zvýraznenie aktuálnej vetvy a upstreamu farbou.$(git symbolic-ref -q --short HEAD)
je názov aktuálnej vetvy$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))
je upstream aktuálnej vetvy.Keďže reset je potenciálne nebezpečné volanie (najmä s voľbou --hard, stratíte všetky neodovzdané zmeny), najprv vám povie, čo sa chystá urobiť. Napríklad ak sa nachádzate na vetve dev-container so vzdialeným názvom qcpp/dev-container a zadáte git catchup
, zobrazí sa vám výzva:
reset dev-container na qcpp/dev-container? (Y/n)
Ak potom zadáte y alebo jednoducho stlačíte return, vykoná sa reset. Ak zadáte čokoľvek iné, reset sa nevykoná.
Ak chcete byť superbezpeční a programovo zabrániť strate neuskutočnených/neodoslaných zmien, môžete vyššie uvedený alias ďalej vylepšiť pomocou podľa kontrol pre diff-index.
Povinné varovanie: Ak pracujete na verejnom úložisku, na ktorom založili prácu iní ľudia, a potrebujete tento alias, robíte to zle™.