Как получить изменения на ветке в Git

266

Каков наилучший способ получить журнал коммитов на ветке с момента его ветвления от текущей ветки? Мое решение до сих пор:

git log $(git merge-base HEAD branch)..branch

Документация для git-diff указывает, что git diff A...Bэквивалентно git diff $(git-merge-base A B) B. С другой стороны, документация для git-rev-parse указывает, что r1...r2определяется как r1 r2 --not $(git merge-base --all r1 r2).

Почему они разные? Обратите внимание, что это git diff HEAD...branchдает мне нужные мне различия, но соответствующая команда git log дает мне больше, чем я хочу.

В картинках предположим, что это:

         х --- у --- --- г ветви
        /
--- --- б --- с --- --- д е --- ГОЛОВКА

Я хотел бы получить журнал, содержащий коммиты x, y, z.

  • git diff HEAD...branch дает эти коммиты
  • однако git log HEAD...branchдает x, y, z, c, d, e.
Грег Хьюгилл
источник
Вы используете "git log" неправильно для ваших целей, насколько я вижу. Я добавил свой ответ ниже.
PlagueHammer

Ответы:

187

В контексте списка ревизий, A...Bкак git-rev-parseон определяется. git-log принимает список ревизий. git-diffне принимает список ревизий - он принимает одну или две ревизии и определил A...Bсинтаксис, чтобы обозначить, как он определен на git-diffстранице руководства . Если git-diffявно не определить A...B, то этот синтаксис будет недействительным. Обратите внимание, что git-rev-parseсправочная страница описана A...Bв разделе «Указание диапазонов», и все в этом разделе допустимо только в ситуациях, когда допустим диапазон редакций (т. Е. Когда требуется список редакций).

Чтобы получить журнал, содержащий только x, y и z, попробуйте git log HEAD..branch(две точки, а не три). Это идентично git log branch --not HEADи означает все коммиты на ветке, которые не находятся на HEAD.

Лили Баллард
источник
31
Вау, это сбивает с толку. Оказывается, что использование "git diff HEAD..branch" показывает все коммиты (x, y, z, c, d, e), но "git log HEAD..branch" делает именно то, что я хочу, и показывает только x, y ! Это полная противоположность использованию "...".
Грег Хьюгилл
22
git diff HEAD..branchидентична git diff HEAD branch. Здесь нужно помнить, что log принимает список / диапазон ревизий, а diff - нет. Вот почему они по-разному относятся к своим аргам.
Лили Баллард
4
Кажется, что git diff HEAD...branch(три точки) соответствует выводуgit log HEAD..branch
jchook
72
git cherry branch [newbranch]

делает именно то, что вы просите, когда вы находитесь в masterфилиале.

Я также очень люблю:

git diff --name-status branch [newbranch]

Что не совсем то, что вы просите, но все же очень полезно в том же контексте.

skiphoppy
источник
8
'git cherry' выводит список идентификаторов коммитов. Могу ли я преобразовать их в один diff, объединяющий все изменения в каждом коммите?
Джонатан Хартли
1
git cherryэто действительно очень полезно. Спасибо :)
JKP
2
@JonathanHartley Возьмите первый и последний подобные идентификаторы коммитов и бросьте их в gif-diff:, git diff x..zили для моего собственного примера это так git diff 13bc4d..8eda3a.
Towi
3
Трудно понять, какой код должен быть заменен в вашей команде: какой из ветвей или newbranch является ключевым словом, а какой должен быть заменен на пользовательское имя ветки
pal4life
37

То, что вы хотите увидеть, это список исходящих коммитов. Вы можете сделать это используя

git log master..branchName 

или

git log master..branchName --oneline

Где я предполагаю, что «branchName» был создан как отслеживание ветви «master».

Аналогично, для просмотра входящих изменений вы можете использовать:

git log branchName..master
PlagueHammer
источник
1
@ABB, если branchName опущено, по умолчанию используется значение "head", которое в приведенном выше примере фактически является branchName.
PlagueHammer
25

Это похоже на ответ, который я опубликовал: Предварительный просмотр Git push

Добавьте эти функции в свой профиль Bash:

  • gbout - git ветка исходящая
  • gbin - входящая ветка git

Вы можете использовать это как:

  • Если на master: gbin branch1 <- это покажет вам, что находится в branch1, а не в master
  • Если на master: gbout branch1 <- это покажет вам, что в master, а не в branch 1

Это будет работать с любой веткой.

function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}

function gbin {
    echo branch \($1\) has these commits and \($(parse_git_branch)\) does not
    git log ..$1 --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local
}

function gbout {
    echo branch \($(parse_git_branch)\) has these commits and \($1\) does not
    git log $1.. --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local
}
Clintm
источник
16

Похоже на несколько ответов, таких как Alex V's и NDavis, но ни один из них не совпадает.

Когда уже в ветке идет речь

С помощью:

git diff master...

Который сочетает в себе несколько функций:

  • это супер коротко
  • показывает фактические изменения

Обновить:

Вероятно git diff master, так и должно быть , но также показывает diff, а не коммиты, как указано в вопросе.

Майкл Даррант
источник
2
Если вы git co master; git pullсоздали ветвь с тех пор, вы git diff masterне будете использовать ее, чтобы вносить различия ТОЛЬКО в коммиты в указанной ветке.
Гиваль
1
Или указать ветки явно: git diff <branch1>...<branch2>покажет изменения, внесенные branch2.
Алекс
10

Добавьте туда -p, чтобы увидеть некоторые изменения файла

git log -p master..branch

Сделайте псевдонимы:

alias gbc="git branch --no-color | sed -e '/^[^\*]/d' -e 's/* \\(.*\\)/\1/'"

alias gbl='git log -p master..\`gbc\`'

Смотрите уникальные коммиты ветви:

gbl
Алекс V
источник
6

Чтобы просмотреть журнал текущей ветви с момента отделения от мастера:

git log master...

Если вы в данный момент используете master, чтобы увидеть журнал другой ветви, так как она разветвляется от master:

git log ...other-branch

NDavis
источник
4
git log --cherry-mark --oneline from_branch...to_branch

(3 точки), но иногда он показывает «+» вместо «=»

nopsoft
источник
3 точки показывают первый коммит на ветке дважды, а две - нет.
TJ Biddle
2

я нашел

git diff <branch_with_changes> <branch_to_compare_to>

более полезным, поскольку вы получаете не только сообщения коммита, но и весь diff. Если вы уже находитесь в ветке, в которой хотите увидеть изменения и (например) хотите увидеть, что изменилось в мастере, вы можете использовать:

git diff HEAD master
Доминик Эренберг
источник