Как изменить коммит с его родителем?


460

Помимо написания псевдонима или сценария, есть ли более короткая команда для получения diff для конкретного коммита?

git diff 15dc8^..15dc8

Если вы дадите только один идентификатор фиксации git diff 15dc8, он будет отличаться от того, который зафиксирован для HEAD.


Самое классное в этом - то, что это будет работать с «git difftool», используя инструменты для показа diff.
2010 года

Для справки, ответ на этот другой вопрос иллюстрирует, как вы могли бы настроить псевдоним на основе bash для упрощения вышесказанного: stackoverflow.com/questions/3321492/…
Ник

Ответы:


641

Использование git show $COMMIT. Он покажет вам сообщение в журнале для коммита и различия в этом конкретном коммите.


45
Жаль, что он не может использовать difftool :(
orip

1
@orip, вы всегда можете установить GIT_EXTERNAL_DIFF для скрипта, который делает то же самое, что и ваш difftool.
рабство

7
Я предпочитаю ответ Якубаребского, так как приведенное здесь выражение коммита будет работать во многих контекстах: stackoverflow.com/a/449128/992887
RichVel

1
Если не отображается diff, вероятно, нет никаких реальных изменений, например, для коммита слияния
Devin G Rhode

6
@PTWithy: Вопрос был: «Есть ли более короткая команда для получения diff для определенного коммита?», На который отвечает этот вопрос.
Mipadi

439

Использование:

git diff 15dc8^!

как описано в следующем фрагменте man- страницы git-rev-parse (1) (или в современной man-странице git gitrevisions (7) ):

Существуют два других сокращения именования набора, сформированного коммитом и его родительскими коммитами. Обозначение r1 ^ @ означает всех родителей r1. r1 ^! включает коммит r1, но исключает всех его родителей.

Это означает, что вы можете использовать его 15dc8^!как сокращенное обозначение в 15dc8^..15dc8любом месте git, где требуются изменения. Для команды diffgit diff 15dc8^..15dc8 это понимается как git diff 15dc8^ 15dc8, что означает разницу между родителем commit ( 15dc8^) и commit ( 15dc8).

Примечание : описание в git-rev-parse(1)man-странице говорит о диапазонах ревизий , где он должен работать и для фиксации слияния, с более чем одним родителем. Тогда r1^!" r1 --not r1^@" то есть " r1 ^r1^1 ^r1^2 ..."


Кроме того, вы можете использовать, git show COMMITчтобы получить описание фиксации и diff для фиксации. Если вы хотите только diff, вы можете использоватьgit diff-tree -p COMMIT


7
Это должен быть принятый ответ, он намного аккуратнее. Тем не менее, последнее предложение выдержки из git-rev-parse довольно запутанно - похоже, оно означает «диапазон от родителя этого коммита до этого коммита».
RichVel

1
@RichVel: это немного сбивает с толку, потому что он пытается описать также ситуацию, когда commit имеет более одного родителя (это коммит слияния). r1 ^! работает как положено и тогда.
Якуб Наребски

@ JakubNarębski: хороший вопрос, может быть, вы могли бы отредактировать свой ответ, чтобы обобщить ваше понимание дел с одним родителем и с несколькими родителями - отдельные заявления по каждому из них могут быть легче для понимания.
RichVel

1
@ JakubNarębski: да, намного лучше! Я сейчас использую этот ярлык все время - спасибо.
RichVel

1
^!Родительские сокращенное обозначение работает должным образом с difftool для нормальных фиксаций , но разница сторнируется для слияния фиксаций. Почему так?
СЧАСТЛИВЫЕ

56

Если вы знаете, как далеко назад, вы можете попробовать что-то вроде:

# Current branch vs. parent
git diff HEAD^ HEAD

# Current branch, diff between commits 2 and 3 times back
git diff HEAD~3 HEAD~2

Приор совершает работу примерно так:

# Parent of HEAD
git show HEAD^1

# Grandparent
git show HEAD^2

Существует множество способов указать коммиты:

# Great grandparent
git show HEAD~3

Смотрите эту страницу для деталей .


2
HEAD ^ 2 - это не прародитель, если HEAD ^ 1 - папочка, то HEAD ^ 2 - это мама. Используйте HEAD ~ 2 для папочки.
Бинар

11

Как указывает @mipadi, вы можете использовать git show $COMMIT, но это также показывает некоторые заголовки и сообщение фиксации. Если вы хотите прямой дифференциал, используйте git show --pretty=format:%b $COMMIT.

Это, очевидно, не очень короткая рука, поэтому я держу этот псевдоним в моем .gitconfig

    [alias]
      sd = show --pretty=format:%b

Это позволяет мне использовать git sd $COMMITдля показа различий .


1
Этот псевдоним может включать --color, который облегчает чтение: sd = show --color --pretty = format:% b
RichVel

@RichVel Действительно! Очень хороший момент. Если у вас в git включены цвета по умолчанию, этот переключатель вам не понадобится. Это то, что я обычно делаю.
Ойстейн Штаймлер

5

Многие из упомянутых примеров (например git diff 15dc8^!, или git diff 15dc8^..15dc8) не работают, если вы используете zsh и имеете extendedglobнабор опций. Вы можете исправить это одним из следующих трех способов:

  1. unsetopt extendedglob (и / или удалить его из .zshrc)

  2. setopt NO_NOMATCH (и / или установите его в .zshrc)

  3. избегать кареты и стучать каждый раз с обратной косой чертой, например git diff 15dc8\^\!



2

Решение Павла выше сделало то, на что я надеялся.

$ git diff HEAD^1

Кроме того, полезно добавить псевдонимы, такие как упомянутые hobs, если вы поместите следующее в раздел [alias] вашего файла ~ / .gitconfig, вы можете использовать сокращение для просмотра различий между головой и предыдущим.

[alias]
    diff-last = diff HEAD^1

Затем, запустив $ git diff-last, вы получите ваш результат. Обратите внимание, что это также будет включать в себя любые изменения, которые вы еще не зафиксировали, а также разницу между фиксациями. Если вы хотите игнорировать изменения, которые вы еще не зафиксировали, вы можете использовать diff, чтобы сравнить HEAD с его родителем напрямую:

$ git diff HEAD^1 HEAD

0

Использует псевдонимы, поэтому не дает точного ответа на ваш вопрос, но я считаю, что они полезны для выполнения ваших намерений ...

alias gitdiff-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"

alias gitlog-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.