Використовуючи Git, покажіть усі комітети, які знаходяться в одній гілці, але не в іншій


465

У мене є стара гілка, яку я хотів би видалити. Однак перш ніж це зробити, я хочу перевірити, чи всі зобов’язання, зроблені в цій галузі, були в якийсь момент об'єднані в іншу гілку. Таким чином, я хотів би побачити всі комісії, внесені до моєї поточної гілки, які не були застосовані до будь-якої іншої гілки [або, якщо це неможливо без певного сценарію, як можна побачити всі комітети в одній гілці, які не були застосовані до іншої заданої гілки?].


Для переліку відсутніх комітетів між двома гілками ви можете скористатися Compare-branches.py bitbucket.org/aakef/compare-git-branches
Бернд Шуберт

Відповіді:


320

Ви, мабуть, просто хочете

git branch --contains branch-to-delete

У цьому списку будуть перелічені всі гілки, які містять комітети "відгалуження до видалення". Якщо він повідомляє більше, ніж просто "гілка для видалення", гілка об'єднана.

Ваші альтернативи насправді є лише синтаксисними речами. наприклад, git log one-branch..another-branchпоказує все, що one-branchпотрібно, щоб все another-branchбуло.

Можливо, вас також зацікавить git show-branchяк спосіб побачити, що де.


2
+1. Дивіться також stackoverflow.com/questions/850607 / ...
VonC

1
Рядок "Якщо він щось повідомляє, гілка об'єдналася" може бути неправильно інтерпретована: якщо git branch --contains some-branchтільки повертається some-branch, то вона щось повертає, але вона не була об'єднана.
Плутанина

5
Зауважте, що git log foo..barбудуть показані коміти між останньою смугою базу та останньою версією foo, але не будуть пропущені інші комісії з подальшого часу назад. Щоб побачити все в барі, але не в foo, скористайтеся рішенням @ jimmyorr.
Пол А Юнгвірт

555

Щоб побачити список, які комітети є в одній гілці, а не в іншій, використовуйте журнал git:

git log --no-merges oldbranch ^newbranch

... тобто показувати журнали фіксації для всіх комірок на oldbranch, які не є на newbranch. Ви можете перелічити декілька гілок, щоб їх включити та виключити, наприклад

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

Примітка. У Windows ^- це клавіша виходу, тому її потрібно виконувати за допомогою іншого ^:

git log --no-merges oldbranch ^^newbranch

2
Я виявив, що шукає git порівняти коміти двох гілок.
Користувач

25
Це саме те, що я шукав. Але використання тут ^як префікса мене збентежило. У цьому контексті це означає виключити цю галузь. Використання ^як суфікса буде відносним посиланням на батьківський комітет цієї гілки.
Джо Флінн

4
дуже корисна подяка Мені цікаво, чому потрібен прапор --no-merges? Звичайно, хочеться бачити і ці зобов’язання?
Макс Маклеод

2
Хотіли б використовувати gitk для цього? Просто використовуйте gitk oldbranch ^newbranch --no-merges(випробувано з git 1.8.1.1). Бічна примітка, для мене ^означає включення HEAD філії newbranch.
Метт

2
@NazariiGudzovatyi - так, є: "-cherry-pick". Є величезна кількість варіантів для входу на сторінку документації
romeara

91

Щоб показати комітети у oldbranch, але не у newbranch:

git log newbranch..oldbranch

Щоб показати різницю за цими комітами (зауважте, є три крапки):

git diff newbranch...oldbranch

Ось документ із ілюстрацією діаграми https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges


Дивіться коментар Пола А Юнгвірта вище. Здається, це пропустить деякі старі зобов’язання?
Жалюгідна змінна

2
Я не впевнений, що означають старі комісії. Подвійні крапки в основному просять Git вирішити діапазон комітетів, які доступні з одного комітету, але недоступні з іншого. Ось документ із ілюстрацією діаграми git-scm.com/book/en/v2/…
Сюань

1
і якщо ми перебуваємо або в, newbranchабо oldbranch, можемо, git log ..oldbranchабо git log newbranch..відповідно
YakovL

Рішення jimmyorr не спрацювало для мене, але це було завдяки двом крапкам ..між іменами реф. Я також використовував --cherry-pickваріант, щоб приховати комітети, які є на обох гілках, але вони мають різний хеш, оскільки їх вибирали з однієї гілки в іншу.
flawyte

58

Для тих, хто все ще шукає просту відповідь, ознайомтеся з git cherry . Він порівнює фактичні відмінності замість хешів фіксації. Це означає, що він вміщує в себе товари, які були вишневі або зібрані.

Перший замовлення відділення, яке потрібно видалити:

git checkout [branch-to-delete]

то використовуйте git cherry, щоб порівняти його з вашою основною галуззю розвитку:

git cherry -v master

Приклад виводу:

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

Примітка. -vПрапор повинен містити повідомлення про фіксацію разом із хешем SHA.

Рядки з позначкою "+" попереду знаходяться в гілці для видалення, але не в головній гілці. Ті, у кого "-" попереду, мають рівноцінний фіксатор у ведучому.

Для ДОВІДКОВАНИХ зобов'язань, які не входять до складу майстра, поєднайте вишню з грепом:

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

Приклад виводу:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message

Я спробував це, але він все ще повідомляє, що у fb (гілка функції) є багато комітетів, які відсутні в mb (основна гілка). Однак, якщо я перебуваю на fb і роблю git diff mb, я не бачу відмінностей. Я все-таки використовував rebase і все розбив. Я майже впевнений, що це, але я просто хочу бути певним. Якщо це так, то я збираюся уникати розтирань, якщо це взагалі можливо; Я перебуваю в "без втраченого інформаційного табору". Цікаво, чи можна було б додати режим відображення журналу, який може відображати злиття так, як якщо б вони були відновлюваними, щоб зберегти історію чистою та ще не втратити інформацію.
Outis Von Nemo

1
Не впевнений у вашому точному сценарії тут, але якщо ви з’єднали кілька комітетів разом в один і порівнюєте це з іншою гілкою, де коміти є окремими, це точно не буде працювати. У такому випадку ви можете просто скористатися diffутилітою unix для порівняння різних файлів. Або ви можете створити тимчасову гілку і розчасувати всі комісії у тому, що схоже на те, що ви робили з оригінальною гілкою, а потім використовувати це, що, на мою думку, спрацювало б.
Тім S

50

Хоча деякі відповіді, розміщені тут, допоможуть знайти те, що ви шукаєте, наступна підкоманда гіт гілки є більш підходящим рішенням для вашої задачі.

--merged використовується для пошуку всіх гілок, які можна безпечно видалити, оскільки ці гілки повністю містяться HEAD.

Хоча в masterодному можна було виконати команду для перерахування гілок, можна було б безпечно видалити, як-от так:

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

16

Відповідь jimmyorr не працює в Windows. це допомагає --notзамість цього використовувати ^:

git log oldbranch --not newbranch --no-merges

4
Це правильно, +1. Зверніть увагу , однак , що ^підтримується на Windows, але потрібно екранувати, що, в Windows, є (інший) ^: git log oldbranch ^^newbranch --no-merges.
VonC

3
Щоб бути конкретним, він працює в Windows на консолі Powershell, але вимагає додаткових "^" в CMD.
прут

7

Якщо це одна (одна) гілка, яку вам потрібно перевірити, наприклад, якщо ви хочете, щоб ця гілка "B" була повністю об'єднана у гілку "A", ви можете просто зробити наступне:

$ git checkout A
$ git branch -d B

git branch -d <branchname> має безпеку, що "Гілка повинна бути повністю об'єднана в HEAD."

Увага : це фактично видаляє гілку B, якщо вона об'єднана в A.


3

Цей простий скрипт можна використовувати для перегляду комісій, які не об'єднуються

#!/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')

Ви також можете використовувати інструмент git-wtf, який відображатиме стан гілок


0

Просто використовуйте git cherryдля вибору всіх комісій у галузі, newFeature42наприклад:

git cherry -v master newFeature42


-5

Почніть створювати запит на отримання на виклик через службу хостингу git, яку ви використовуєте. Якщо гілка була повністю об'єднана в базову гілку, ви не зможете створити новий PR.

Вам не потрібно насправді робити запит на витяг, просто скористайтеся першим кроком, де ви вибираєте гілки.

Наприклад, на GitHub:

Нема з чим порівняти

Не вдається створити PR для галузей, які були об'єднані.

Це не використовує git у командному рядку, але я часто вважаю, що корисно використовувати інші інструменти, які є у вашому розпорядженні, з чіткою ментальною моделлю, а не намагатися запам'ятати іншу таємну команду git.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.