Bagaimana cara mengganti cabang lokal dengan cabang jarak jauh seluruhnya di Git?

779

Saya memiliki dua cabang:

  1. cabang lokal (cabang tempat saya bekerja)
  2. cabang terpencil (publik, hanya komit yang teruji pergi ke sana)

Baru-baru ini saya serius mengacaukan cabang lokal saya.

Bagaimana saya mengganti cabang lokal sepenuhnya dengan yang jauh, sehingga saya dapat melanjutkan pekerjaan saya dari tempat cabang terpencil sekarang?

Saya sudah mencari SO dan memeriksa ke cabang jarak jauh secara lokal tidak memiliki efek apa pun.

YemSalat
sumber
1
Saya tahu jawaban yang diterima memiliki suara 1280, tetapi Anda harus benar-benar mempertimbangkan untuk mengubah jawaban yang diterima ke yang oleh @TTT.
Jamie

Jawaban:

1289
  1. Pastikan Anda telah memeriksa cabang yang Anda ganti (dari komentar Zoltán ).
  2. Mengasumsikan master adalah cabang lokal yang Anda gantikan, dan "asal / master" adalah cabang jarak jauh yang ingin Anda atur ulang:

    git reset --hard origin/master
    

Ini memperbarui cabang KEPALA lokal Anda untuk menjadi revisi yang sama dengan asal / master, dan --hardakan menyinkronkan perubahan ini ke dalam indeks dan ruang kerja juga.

araqnid
sumber
4
Terima kasih atas saran Anda, saya sudah 'takut' menggunakan --hard dan --force, jadi saya hanya memilih solusi yang tidak menggunakannya.
YemSalat
13
@KonstantinLevin: ah ya, penamaan opsi-opsi itu agak menjengkelkan. git resetsecara default akan mengecoh cabang Anda saat ini dan menyinkronkan indeks. --softakan melewati pembaruan indeks, --hardjuga akan menyinkronkan ruang kerja. Pengalaman saya sendiri menggunakan --hardsebagian besar waktu, kecuali ketika saya ingin membatalkan komit terakhir (yang adil git reset HEAD^)
araqnid
9
Setelah memiliki lebih banyak pengalaman dengan git, saya yakin ini adalah solusi yang lebih baik, terima kasih.
YemSalat
24
mungkin Anda harus mengambil dulu:git fetch origin remote_branch
b1r3k
53
Anda harus mencatat bahwa ini akan menggantikan cabang mana saja yang saat ini aktif dengan konten master . Jadi, jika Anda menggunakan mis. Cabang-fitur, ia akan mengganti semua komitmennya master, jadi pastikan Anda telah memeriksa cabang yang Anda ganti terlebih dahulu.
Zoltán
218

Itu semudah tiga langkah:

  1. Hapus cabang lokal Anda: git branch -d local_branch
  2. Ambil cabang jarak jauh terbaru: git fetch origin remote_branch
  3. Bangun kembali cabang lokal berdasarkan yang jauh: git checkout -b local_branch origin/remote_branch
adamsmith
sumber
7
Sebenarnya apa yang dikatakan @araqnid benar dan lebih ringkas. Saya telah mengujinya dan Anda dapat mencobanya juga.
adamsmith
Wow, checkout checkout -b local_branch origin / remote_branch hebat! Saya selalu melakukan ini dalam dua perintah terpisah. Terima kasih!
kendepelchin
11
Anda mungkin perlu melakukan git branch -D local_branchdi langkah pertama jika cabang Anda tidak digabung.
szeryf
terima kasih, saya mengalami kesulitan ketika menggunakan gitflow, setelah menerbitkan cabang dan kemudian menyelesaikannya, saya ingin pergi ke cabang yang dihapus, dan solusi Anda adalah satu-satunya yang bekerja, tarikan sepertinya tidak berfungsi .. atau saya mave belum menggunakannya dengan baik -
Decebal
2
kita harus memastikan bahwa cabang saat ini bukan yang akan dihapus.
a_secenthusiast
43
git branch -D <branch-name>
git fetch <remote> <branch-name>
git checkout -b <branch-name> --track <remote>/<branch-name>
Sailesh
sumber
Apa yang dilakukan bagian --track?
eonist
3
@ GitSync, Ini yang git help branchdikatakan tentang --track. When creating a new branch, set up branch.<name>.remote and branch.<name>.merge configuration entries to mark the start-point branch as "upstream" from the new branch. This configuration will tell git to show the relationship between the two branches in git status and git branch -v. Furthermore, it directs git pull without arguments to pull from the upstream when the new branch is checked out. Saya memperbaiki perintah ini dalam jawabannya. Terima kasih telah menyampaikan poinnya.
Sailesh
Jadi dalam istilah awam: itu menambahkan URL jarak jauh ke cabang baru. Jadi mereka sinkron selamanya. Boleh dikatakan.
eonist
2
Anda dapat mengatakan bahwa ini hanya untuk kenyamanan. Jika Anda melakukannya git status, itu akan melaporkan jika cabang lokal Anda ada di depan atau di belakang cabang jarak jauh jika Anda memiliki mereka yang terkait. Selain itu, Anda dapat melakukan git pull(atau push) alih-alih penuh git pull <remote> <branch>jika Anda telah mengatur cabang Anda untuk dilacak <remote/branch>.
Sailesh
22

Ganti semuanya dengan cabang jarak jauh; tetapi , hanya dari komit yang sama dengan cabang lokal Anda yang aktif:

git reset --hard origin/some-branch

ATAU , dapatkan yang terbaru dari cabang jarak jauh dan ganti semuanya:

git fetch origin some-branch
git reset --hard FETCH_HEAD

Selain itu, jika perlu, Anda dapat menghapus file & direktori yang tidak terlacak yang belum Anda lakukan:

git clean -fd
sedikit kurang
sumber
The git cleanperintah melakukannya untuk saya. git reset hard origin/masterjangan menghapus file yang tidak terlacak. Terima kasih!
Mornor
9

Cara teraman dan terlengkap untuk mengganti cabang lokal saat ini dengan remote:

git stash
git merge --abort
git rebase --abort
git branch -M yourBranch replaced_yourBranch
git fetch origin yourBranch:yourBranch
git checkout yourBranch

The stashgaris menyimpan perubahan yang Anda belum berkomitmen. The branchgaris bergerak cabang Anda ke nama yang berbeda, membebaskan nama asli. The fetchgaris mengambil salinan terbaru dari remote. The checkoutgaris recreates cabang asli sebagai cabang pelacakan.

Atau sebagai fungsi bash:

replaceWithRemote() {
    yourBranch=${1:-`git rev-parse --abbrev-ref HEAD`}
    git stash
    git merge --abort
    git rebase --abort
    git branch -M ${yourBranch} replaced_${yourBranch}_`git rev-parse --short HEAD`
    git fetch origin ${yourBranch}:${yourBranch}
    git checkout ${yourBranch}
}

yang mengubah nama cabang saat ini menjadi sesuatu seperti replace_master_98d258f.

Joshua S
sumber
Mungkin ingin dimasukkan git stash popdalam alur kerja itu. Jika Anda ingin menerapkan kembali file simpanan Anda.
eonist
Apa yang Anda lakukan dengan cabang simpanan? Saya khawatir itu akan muncul lagi di suatu tempat di masa depan lama setelah saya lupa untuk apa itu.
Scott Biggs
1
@ScottBiggs Jika Anda ingin menghapus cabang simpanan, gunakan "git stash clear".
Mark A. Durham
5

Saya agak terkejut belum ada yang menyebutkan ini; Saya menggunakannya hampir setiap hari:

git reset --hard @{u}

Pada dasarnya, @{u}hanya singkatan untuk cabang hulu yang dilacak oleh cabang Anda saat ini. Misalnya, ini biasanya sama dengan origin/[my-current-branch-name]. Itu bagus karena itu cabang agnostik.

Pastikan untuk git fetchpertama - tama mendapatkan salinan terbaru dari cabang jarak jauh.

TTT
sumber
1
yang terlihat sangat bagus, saya bosan menyalin dan menempelkan nama cabang untuk diatur ulang!
pedroct92
1
Saya memiliki beberapa contoh di mana saya menambahkan jawaban untuk pertanyaan lama, dan jawaban saya berhasil naik ke papan peringkat. Saya harap yang ini.
Jamie
3

Ini dapat dilakukan dengan berbagai cara, terus mengedit jawaban ini untuk menyebarkan perspektif pengetahuan yang lebih baik.

1) Atur ulang dengan keras

Jika Anda bekerja dari cabang pengembangan jarak jauh, Anda dapat mengatur ulang KEPALA ke komit terakhir di cabang jarak jauh seperti di bawah ini:

git reset --hard origin/develop

2) Hapus cabang saat ini, dan checkout lagi dari repositori jarak jauh

Menimbang, Anda sedang bekerja mengembangkan cabang di repo lokal, yang disinkronkan dengan cabang jarak jauh / kembangkan, Anda dapat melakukan seperti di bawah ini:

git branch -D develop
git checkout -b develop origin/develop

3) Batalkan Penggabungan

Jika Anda berada di antara penggabungan yang buruk (keliru dilakukan dengan cabang yang salah), dan ingin menghindari penggabungan untuk kembali ke cabang terbaru seperti di bawah ini:

git merge --abort

4) Batalkan Pengguguran

Jika Anda berada di antara rebase buruk, Anda dapat membatalkan permintaan rebase seperti di bawah ini:

git rebase --abort
Amit Kaneria
sumber
2

Anda dapat melakukan seperti yang dikatakan @Hugo dari @Laurent, atau Anda dapat menggunakan git rebaseuntuk menghapus komit yang ingin Anda singkirkan, jika Anda tahu yang mana. Saya cenderung menggunakan git rebase -i head~N(di mana N adalah angka, memungkinkan Anda untuk memanipulasi komit N terakhir) untuk operasi semacam ini.

ksol
sumber
Sebenarnya itu adalah perintah 'git rebase' yang mengacaukan semuanya, lalu beberapa gabungan paksa dan pengaturan ulang yang keras .. Lagi pula, apa yang saya cari hanyalah beberapa cara mudah untuk menarik seluruh repo dari server jauh tanpa penggabungan.
YemSalat
2

The jawaban yang dipilih benar-benar benar , namun tidak meninggalkan saya dengan terbaru komit / dorongan ...

Jadi buat saya:

git reset --hard dev/jobmanager-tools
git pull  ( did not work as git was not sure what branch i wanted)

Karena saya tahu saya ingin mengatur sementara cabang hulu saya selama beberapa minggu ke cabang tertentu (sama seperti yang saya alihkan / periksa sebelumnya dan melakukan hard reset)

Jadi SETELAH reset

git branch --set-upstream-to=origin/dev/jobmanager-tools
git pull
git status    ( says--> on branch  dev/jobmanager-tools 
Tom Stickel
sumber
1

Jika Anda ingin memperbarui cabang yang saat ini tidak diperiksa, Anda dapat melakukannya:

git fetch -f origin rbranch:lbranch
kqr
sumber
0

Seperti yang diberikan pada penjelasan yang dipilih, git reset bagus. Tetapi saat ini kita sering menggunakan sub-modul: repositori di dalam repositori. Sebagai contoh, Anda jika Anda menggunakan ZF3 dan jQuery dalam proyek Anda, kemungkinan besar Anda ingin mereka diklon dari repositori aslinya. Dalam kasus seperti itu git reset tidak cukup. Kita perlu memperbarui submodules ke versi yang tepat yang didefinisikan dalam repositori kami:

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

git submodule foreach git submodule update

git status

itu sama seperti Anda akan datang (cd) secara rekursif ke direktori kerja setiap sub-modul dan akan berjalan:

git submodule update

Dan sangat berbeda dari

git checkout master
git pull

karena sub-modul menunjuk bukan ke cabang tetapi ke komit.

Dalam hal ini ketika Anda secara manual checkout beberapa cabang untuk 1 atau lebih submodul yang dapat Anda jalankan

git submodule foreach git pull
Eugene Kaurov
sumber
Harap berikan penjelasan, terutama saat menjawab pertanyaan setua ini. Jawaban Anda tidak membantu apa adanya.
Erik A
Jawaban yang diterima sudah diajukan git reset --hard. Ini menambah sedikit nilai.
florisla
0
git reset --hard
git clean -fd

Ini bekerja untuk saya - bersih menunjukkan semua file yang dihapus juga. Jika itu memberi tahu Anda bahwa Anda akan kehilangan perubahan, Anda harus menyimpannya.

Travis Heeter
sumber
-6

Cara jelek tapi sederhana: hapus folder lokal Anda, dan tiru repositori jarak jauh lagi.

Hugo
sumber
10
Atau cukup hapus cabang dan periksa kembali.
laurent
Yap, saya kira itulah yang akan saya lakukan jika saya tidak menemukan cara melakukannya dengan cara yang kurang 'jelek'
YemSalat
2
Jelek terkadang bermanfaat untuk diketahui. Saya benar-benar berharap orang tidak akan merendahkan hal-hal hanya karena mereka bukan cara konvensional: pasti ada alasan yang lebih rasional untuk melakukan downvoting ... dan itu harus diberikan. Git adalah hal yang mencapai hasil. Ini bukan semacam teks suci.
mike rodent
3
Saya tidak mengerti downvotes :-( Ya, itu tidak bagus, dll. Tapi itu bisa bekerja paling baik dalam beberapa kasus ... maaf @Hugo
silverdr
@ Hugo, Setuju. Sesuatu yang misterius dan bau terjadi pada cabang pengembangan lokal saya, dan baik Ketua Tim dan Manajer Teknik menyarankan, di antara solusi yang lebih elegan, untuk hanya (zip, menyalin, dan menyimpan pekerjaan fitur saya, kemudian) nuke repo lokal dan ditutup kembali.
AmitaiB