Perlu mengatur ulang cabang git ke versi asal

439

Saya secara tidak sengaja mengerjakan cabang yang seharusnya tidak saya tempati untuk sementara waktu, jadi saya cabut cabang itu sehingga memberi nama yang sesuai. Sekarang saya ingin menimpa cabang saya seharusnya tidak ke versi dari asal (github). Apakah ada cara mudah untuk melakukan ini? Saya mencoba menghapus cabang dan mengatur ulang cabang pelacakan, tetapi itu hanya memberi saya versi yang saya kerjakan lagi.

Brad Herman
sumber
Dengan Git 2.23 (Agustus 2019): git switch -C mybranch origin/mybranch. Lihat jawaban saya yang diedit di bawah ini
VonC

Jawaban:

815

Jika Anda belum mendorong ke asal, Anda dapat mengatur ulang cabang Anda ke cabang hulu dengan:

git checkout mybranch
git reset --hard origin/mybranch

(Pastikan Anda merujuk komit terbaru Anda di cabang terpisah, seperti yang Anda sebutkan dalam pertanyaan Anda)

Perhatikan bahwa tepat setelah reset, mybranch@{1}merujuk ke komit yang lama, sebelum reset.

Tetapi jika Anda sudah mendorong, lihat " Buat cabang git, dan kembalikan yang asli ke status hulu " untuk opsi lainnya.


Dengan Git 2.23 (Agustus 2019) , yang akan menjadi satu perintah: git switch.
Yaitu:git switch -C mybranch origin/mybranch

Contoh

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

Itu mengembalikan indeks dan pohon kerja, seperti sebuah git reset --hardwasiat.


Seperti dikomentari oleh Brad Herman , a reset --hardakan menghapus file baru atau mereset file yang dimodifikasi ke HEAD .

Sebenarnya, untuk memastikan Anda memulai dari "clean slate", git clean -f -dsetelah reset akan memastikan pohon yang bekerja persis sama dengan cabang yang baru Anda setel ulang.


Posting blog ini menyarankan alias tersebut ( masterhanya untuk cabang, tetapi Anda dapat menyesuaikan / memperluasnya):

[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

Maka Anda dapat mengetik:

git resetupstream

atau

git resetorigin
VONC
sumber
26
ini akan HAPUS perubahan UNSTAGED / STAGED (dari --hard)
Peter Ehrlich
5
Saya telah menggunakan git reset --hard origin/mybranchperintah beberapa kali ketika saya tidak peduli dengan perubahan lokal dan hanya ingin salinan bersih yang cocok dengan aslinya. Namun, hari ini, ini tidak berhasil - saya masih memiliki beberapa file baru, tidak dipentaskan, dan git terus menjanjikan saya bahwa itu di HEAD. Catatan tentang git clean -f -dmemperbaikinya dengan menghapus semua file baru yang tidak saya inginkan.
Matthew Clark
@MatthewClark Itu diharapkan: lihat komentar di stackoverflow.com/q/4327708/6309
VonC
1
Bagus! Juga sering saya gunakan git reset --hard HEADuntuk kembali ke komit sebelumnya, mengabaikan perubahan apa pun
daronwolff
Apakah ini mungkin dengan sourctree juga?
Lonzak
20

Dengan asumsi inilah yang terjadi:

# 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

Kemudian Anda menyadari bahwa Anda membuat perubahan pada cabang yang salah.

git checkout -b mybranch    # you create the correct branch and switch to it

Tetapi mastermasih menunjuk komit Anda. Anda ingin menunjuk ke tempat yang ditunjuk sebelumnya.

Larutan

Cara termudah adalah:

git branch --force master origin/master

Cara lain adalah:

git checkout master
git reset --soft origin/master
git checkout mybranch

Perhatikan bahwa menggunakan reset --hardakan menyebabkan perubahan yang tidak dikomit Anda menjadi hilang ( tests.pydalam contoh saya).

pengguna28667
sumber
Itu tampaknya lebih aman daripada dalam jawaban saya;) +1
VonC
8

Saya memiliki repo pribadi di server dan secara teratur rebase / paksa-push, yang membuatnya perlu untuk mereset cabang lokal di komputer saya yang lain sering. Karena itu saya membuat alias "catchup" berikut, yang memungkinkan melakukan ini untuk cabang saat ini. Tidak seperti jawaban lainnya, tidak ada nama cabang yang di-hardcode dalam alias ini.

Pegang erat-erat.

[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"

Diformat dengan benar (tidak akan bekerja dengan baris baru di .gitconfig) seperti ini:

"
!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
"
  • The \\033[0;33mdan \\033[0madalah untuk menekankan cabang saat ini dan hulu dengan warna.
  • $(git symbolic-ref -q --short HEAD) adalah nama cabang saat ini
  • $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)) adalah hulu dari cabang saat ini.

Karena reset adalah panggilan yang berpotensi berbahaya (terutama dengan opsi --hard, Anda akan kehilangan perubahan yang tidak dikomit), yang pertama kali memberitahu Anda apa yang akan dilakukan. Misalnya jika Anda menggunakan wadah dev cabang dengan remote bernama qcpp / dev-container dan Anda masuk git catchup, Anda akan diminta:

reset dev-container ke qcpp / dev-container? (Y / n)

Jika Anda mengetikkan y atau menekan kembali, itu akan melakukan reset. Jika Anda memasukkan hal lain, pengaturan ulang tidak akan dilakukan.

Jika Anda ingin menjadi super aman dan secara terprogram mencegah kehilangan perubahan yang tidak dipentaskan / tidak dikomit, Anda dapat mucikari alias di atas lebih lanjut dengan cek sesuai untuk diff-index .

Kata peringatan wajib: Jika Anda mengerjakan repositori publik yang digunakan orang lain untuk mengerjakannya, dan Anda memerlukan alias ini, Anda salah melakukannya ™ .

DerManu
sumber
1

Saya mencoba ini dan itu tidak me-reset cabang saya saat ini ke github jarak jauh saya terbaru. Saya mencari di Google dan menemukan https://itsyndicate.org/blog/how-to-use-git-force-pull-properly/

yang disarankan

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

Saya ingin mengatur ulang cabang v8 saya jadi saya lakukan

git fetch origin v8
git reset --hard origin/v8

dan itu berhasil

SimpleSi
sumber
Yah, bagus bahwa Anda menyebutkan mengambil. Saya melakukannya sekali tanpa dan mengatur ulang semuanya menjadi 2 tahun yang lalu :)
Adam