Menggunakan Git, tunjukkan semua komit yang ada di satu cabang, tetapi tidak yang lain

465

Saya memiliki cabang lama, yang ingin saya hapus. Namun, sebelum melakukan itu, saya ingin memeriksa bahwa semua komitmen yang dilakukan untuk cabang ini pada beberapa titik digabung menjadi beberapa cabang lainnya. Jadi, saya ingin melihat semua komit dibuat pada cabang saya saat ini yang belum diterapkan ke cabang lain [atau, jika ini tidak mungkin tanpa beberapa skrip, bagaimana seseorang melihat semua komit dalam satu cabang yang belum diterapkan ke cabang lain yang diberikan?].

sircolinton
sumber
Untuk membuat daftar komit yang hilang di antara dua cabang, Anda dapat menggunakan compare-branches.py bitbucket.org/aakef/compare-git-branches
Bernd Schubert
Terkait: stackoverflow.com/q/1419623/1959808
Ioannis Filippidis

Jawaban:

321

Anda mungkin hanya ingin

git branch --contains branch-to-delete

Ini akan mendaftar semua cabang yang berisi komit dari "branch-to-delete". Jika itu melaporkan lebih dari sekadar "branch-to-delete", cabang telah digabungkan.

Alternatif Anda benar-benar hanya hal-hal sintaks daftar ulang. misalnya git log one-branch..another-branchmenunjukkan semua yang one-branchperlu memiliki semuanya another-branch.

Anda juga mungkin tertarik git show-branchsebagai cara untuk melihat di mana.

Dustin
sumber
1
Baris 'Jika melaporkan sesuatu, cabang telah bergabung' dapat disalahartikan: jika git branch --contains some-branchhanya kembali some-branch, maka itu akan mengembalikan sesuatu, tetapi belum digabung.
Kebingungan
5
Perhatikan bahwa git log foo..barakan menampilkan komit antara bilah terbaru dan foo terbaru, tetapi tidak ada komit lain yang hilang dari masa lalu. Untuk melihat semuanya di bar tetapi tidak di foo, Anda harus menggunakan solusi @ jimmyorr.
Paul A Jungwirth
556

Untuk melihat daftar komit yang berada di satu cabang tetapi bukan yang lain, gunakan git log:

git log --no-merges oldbranch ^newbranch

... yaitu, tampilkan log komit untuk semua komit pada oldbranch yang tidak pada newbranch. Anda dapat membuat daftar beberapa cabang untuk dimasukkan dan dikecualikan, misalnya

git log  --no-merges oldbranch1 oldbranch2 ^newbranch1 ^newbranch2

Catatan: pada Windows ^adalah kunci pelarian, sehingga harus diloloskan dengan yang lain ^:

git log --no-merges oldbranch ^^newbranch
jimmyorr
sumber
2
Saya menemukan itu mencari komit git membandingkan dua cabang.
Pengguna
25
Inilah yang saya cari. Tapi, menggunakan ^awalan di sini membuatku bingung. Dalam konteks ini ini berarti mengecualikan cabang itu. Menggunakan ^sebagai akhiran akan menjadi referensi relatif ke induk yang melakukan dari cabang itu.
Joe Flynn
4
terima kasih sangat berguna. Saya ingin tahu, mengapa bendera --no-merge diperlukan? Tentunya seseorang ingin melihat komitmen itu juga?
Max MacLeod
2
Ingin menggunakan gitk dengan ini? Cukup gunakan gitk oldbranch ^newbranch --no-merges(Diuji dengan git 1.8.1.1). Catatan tambahan, bagi saya ^berarti kepala HEAD inklusif dari cabang newbranch.
Matt
2
@NazariiGudzovatyi - ya, ada: "-cherry-pick". Ada sejumlah besar opsi untuk masuk pada halaman dokumentasi
romeara
91

Untuk menampilkan komit di oldbranch tetapi tidak di newbranch:

git log newbranch..oldbranch

Untuk menunjukkan perbedaan dengan komit ini (perhatikan ada tiga titik):

git diff newbranch...oldbranch

Inilah dokumen dengan ilustrasi diagram https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges

Xuan
sumber
Lihat komentar Paul A Jungwirth di atas. Tampaknya ini akan kehilangan beberapa komitmen lama?
Variabel sengsara
2
Saya tidak yakin apa artinya komit lama. Titik ganda pada dasarnya meminta Git untuk menyelesaikan serangkaian komitmen yang dapat dijangkau dari satu komit tetapi tidak dapat dijangkau dari yang lain. Ini adalah dokumen dengan ilustrasi digram git-scm.com/book/en/v2/…
Xuan
1
dan jika kita berada di salah satu newbranchatau oldbranch, kita dapat melakukan git log ..oldbranchatau git log newbranch..masing
YakovL
solusi jimmyorr tidak bekerja untuk saya, tetapi yang ini berkat dua titik di ..antara nama referensi Saya juga menggunakan --cherry-pickopsi untuk menyembunyikan komit yang ada di kedua cabang tetapi memiliki hash yang berbeda karena mereka dipilih dari satu cabang ke cabang lainnya.
flawyte
58

Bagi mereka yang masih mencari jawaban sederhana, lihat git cherry . Ini membandingkan diffs yang sebenarnya daripada melakukan hash. Itu berarti mengakomodasi komitmen yang telah diambil atau ditebangi ceri.

Pertama checkout cabang yang ingin Anda hapus:

git checkout [branch-to-delete]

lalu gunakan git cherry untuk membandingkannya dengan cabang pengembangan utama Anda:

git cherry -v master

Contoh output:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message
- 85867e38712de930864c5edb7856342e1358b2a0 Yet another message

Catatan: -vBendera adalah untuk menyertakan pesan komit bersama dengan hash SHA.

Baris dengan tanda '+' di depan ada di cabang untuk dihapus, tetapi bukan cabang master. Mereka yang '-' di depan memiliki komit yang setara dalam master.

Untuk HANYA komitmen yang tidak di master, kombinasikan pick cherry dengan grep:

git cherry -v master | grep "^\+"

Contoh output:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message
Tim S
sumber
Saya sudah mencoba ini, tetapi masih melaporkan bahwa ada banyak komit di fb (cabang fitur) yang tidak ada di mb (cabang utama). Namun, jika saya di fb dan melakukan git diff mb, saya tidak melihat perbedaan. Saya memang menggunakan rebase dan menghancurkan semuanya. Saya hampir yakin inilah sebabnya, tetapi saya hanya ingin memastikan. Jika ini masalahnya, maka saya akan menghindari squashing jika memungkinkan; Saya di "tidak ada info camp yang hilang." Saya bertanya-tanya apakah mungkin untuk menambahkan mode tampilan log yang dapat menampilkan penggabungan seolah-olah mereka diubah untuk menjaga sejarah tetap bersih namun tidak kehilangan info.
Outis Von Nemo
1
Tidak yakin dengan skenario pasti Anda di sini, tetapi jika Anda telah menekan beberapa komit bersama menjadi satu dan membandingkannya dengan cabang lain di mana komit terpisah, ini pasti tidak akan berhasil. Dalam hal ini, Anda mungkin hanya ingin menggunakan diffutilitas unix untuk membandingkan berbagai file. Atau, Anda bisa membuat cabang sementara dan menghancurkan semua komit dalam yang mirip dengan apa yang Anda lakukan dengan cabang asli, dan kemudian menggunakan ini, yang saya pikir akan berhasil.
Tim S
50

Sementara beberapa jawaban yang diposting di sini akan membantu menemukan apa yang Anda cari, sub-perintah cabang git berikut adalah solusi yang lebih cocok untuk tugas Anda.

--merged digunakan untuk menemukan semua cabang yang dapat dihapus dengan aman, karena cabang-cabang itu sepenuhnya berisi HEAD.

Sementara dalam mastersatu dapat menjalankan perintah untuk menghitung cabang yang bisa dihapus dengan aman, seperti:

git branch --merged
  develop
  fpg_download_links
* master
  master_merge_static

# Delete local and remote tracking branches you don't want
git branch -d fpg_download_links
git push origin :fpg_download_links
git branch -d master_merge_static
git push origin :master_merge_static

# There is also a flag to specify remote branches in the output
git branch --remotes --merged
Freddie
sumber
16

Jawaban jimmyorr tidak bekerja di Windows. ini membantu untuk digunakan, --notbukan ^seperti:

git log oldbranch --not newbranch --no-merges
sebeck
sumber
4
Itu benar, +1. Catatan meskipun ^didukung pada Windows, namun kebutuhan untuk melarikan diri, yang, pada Windows, adalah (yang lain) ^: git log oldbranch ^^newbranch --no-merges.
VonC
3
Untuk lebih spesifik, ini berfungsi di Windows di konsol Powershell, tetapi membutuhkan "^" ekstra di CMD.
Rod,
7

Jika itu adalah satu (tunggal) cabang yang perlu Anda periksa, misalnya jika Anda ingin cabang 'B' sepenuhnya digabung menjadi cabang 'A', Anda bisa melakukan hal berikut:

$ git checkout A
$ git branch -d B

git branch -d <branchname> memiliki keamanan yang "Cabang harus sepenuhnya digabung dalam KEPALA."

Perhatian : ini benar-benar menghapus cabang B jika digabungkan menjadi A.

Jakub Narębski
sumber
3

Anda dapat menggunakan skrip sederhana ini untuk melihat komit yang tidak digabungkan

#!/bin/bash
# Show commits that exists only on branch and not in current
# Usage:
#   git branch-notmerge <branchname>
#
# Setup git alias
#   git config alias.branch-notmerge [path/to/this/script]
grep -Fvf <(git log --pretty=format:'%H - %s') <(git log $1 --pretty=format:'%H - %s')

Anda juga dapat menggunakan alat git-wtf yang akan menampilkan status cabang

manRo
sumber
0

Cukup gunakan git cherryuntuk memilih semua komit di cabang newFeature42misalnya:

git cherry -v master newFeature42

Mꜳltus
sumber
-5

Mulai untuk Membuat Permintaan Tarik melalui layanan hosting git yang Anda gunakan. Jika cabang telah sepenuhnya digabung ke cabang dasar, Anda tidak akan dapat membuat PR baru.

Anda tidak perlu benar-benar membuat permintaan tarik, cukup gunakan langkah pertama di mana Anda memilih cabang.

Misalnya, di GitHub:

Tidak ada yang bisa dibandingkan

Tidak dapat membuat PR untuk cabang yang telah digabungkan.

Ini tidak menggunakan git pada baris perintah, tapi saya sering merasa terbantu menggunakan alat lain yang Anda inginkan dengan model mental yang jelas daripada mencoba mengingat perintah git misterius lainnya.

pkamb
sumber