Як я можу створити git diff того, що змінилося з моменту останнього витягування?


77

Я хотів би написати в одній команді, бажано в граблі, наступні дії:

  1. Отримайте версію мого локального сховища git.
  2. Git витягніть останній код.
  3. Git відрізняється від версії, яку я витягнув на кроці # 1, до тієї, яка зараз знаходиться в моєму локальному сховищі.

Іншими словами, я хочу отримати останній код із центрального сховища і негайно згенерувати різницю в тому, що змінилося з моменту останнього витягування.

Відповіді:


92

Ви можете зробити це досить просто за допомогою refspecs.

git pull origin
git diff @{1}..

Це дасть вам різницю в поточній гілці, як вона існувала до та після витягування. Зверніть увагу, що якщо витягування фактично не оновлює поточну гілку, різниця дасть вам неправильні результати. Інший варіант - явний запис поточної версії:

current=`git rev-parse HEAD`
git pull origin
git diff $current..

Я особисто використовую псевдонім, який просто показує мені журнал у зворотному порядку (тобто від найстарішого до найновішого), без злиттів, усіх комітів з мого останнього витягування. Я запускаю це кожного разу, коли мій витяг оновлює гілку:

git config --global alias.lcrev 'log --reverse --no-merges --stat @{1}..

1
@leemes: Хм? git diff HEADпокаже, що змінилося між HEAD та поточною робочою копією. Це не те, що просив тефлоновий Тед.
Лілі Баллард,

Вибачте, я неправильно зрозумів запитання. Я шукав команду, щоб показати свої зміни, коли я востаннє витягнув і приземлився тут. git diff HEADпрацював на те, що мені потрібно (принаймні я здогадуюсь, що це те, що я шукав: D)
leemes

4
Хтось може пояснити (або сказати, де прочитати), що @{1}..саме вимірюється? Просто кинути його в Google не допомагає.
user1129682

5
@ user1129682: Це синтаксис доступу до рефлогов . Без назви гілки це означає доступ до рефлог для поточної гілки. Значення @{1}означає найновіший запис перезапису, наприклад, на що вказувала поточна гілка, перш ніж вказувала на поточний коміт.
Лілі Баллард

2
+1, це правильний спосіб. Вам слід трохи розширити @{1}..нотацію, можливо, явно помістити туди за замовчуванням, а потім показати компактну версію, щоб вона була менш чарівною.
slezica

12

Шлях Грега повинен спрацювати (не я, інший Грег: P). Щодо вашого коментаря, origin - це змінна конфігурації, яку встановлює Git, коли ви клонуєте центральне сховище на локальну машину. По суті, сховище Git пам’ятає, звідки воно взялося. Однак ви можете встановити ці змінні вручну, якщо вам потрібно використовувати git-config.

git config remote.origin.url <url>

де url - віддалений шлях до вашого центрального сховища.

Ось приклад командного файлу, який повинен працювати (я його не тестував).

@ECHO off

:: Retrieve the changes, but don't merge them.
git fetch

:: Look at the new changes
git diff ...origin

:: Ask if you want to merge the new changes into HEAD
set /p PULL=Do you wish to pull the changes? (Y/N)
IF /I %PULL%==Y git pull

1
Зазвичай ви використовуєте git remote set-url origin <url>замість того, git configщоб змінити URL-адресу для пульта дистанційного керування Git . Чи є різниця? Не знаю, але, здається, git remoteце більш підходящий інструмент для роботи.
Colin D Bennett

@ColinDBennett Ви маєте рацію, це git remote set-urlбув би найбільш правильний спосіб зробити це. Я використовував, git configоскільки set-urlне був варіантом, коли я спочатку писав це.
Грег

10

Це дуже схоже на запитання, яке я задавав про те, як отримати зміни на гілці в git . Зверніть увагу, що поведінка git diff проти git log несумісно відрізняється при використанні двох точок проти трьох крапок. Але для вашої програми ви можете використовувати:

git fetch
git diff ...origin

Після цього a git pullоб’єднає зміни у вашу HEAD.


Я не бачу походження, визначене як спеціальне ключове слово для git-diff або git-rev-parse. Ви мали на увазі, що мені потрібно підключити хеш з кроку # 1 як значення для походження? Якщо так, то як мені програмно витягти це значення? Я хотів би для зручності об’єднати всі ці кроки в одну команду / сценарій.
Тефлоновий тед

2
Інший спосіб зробити це - використовувати спеціальну головку FETCH_HEAD, яка відображає результат попереднього отримання. Отже: "git fetch && git diff ... FETCH_HEAD".
Грег Хьюгілл

Я думаю, що це більш відповідна відповідь: git fetchслідом за a git diff origin/branchname- найкращий спосіб перевірити різницю перед витягуванням.
Джуліо Каччін,

4

Якщо ви опустите це у свій профіль bash, ви зможете запустити grin (git віддалений вхідний) та grout (git віддалений вихідний), щоб побачити різницю комітів, що входять та виходять для майстра початківців.

function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}
function gd2 { 
 echo branch \($1\) has these commits and \($2\) does not 
 git log $2..$1 --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local
}
function grin {
 git fetch origin master
 gd2 FETCH_HEAD $(parse_git_branch)
}
function grout {
 git fetch origin master
 gd2 $(parse_git_branch) FETCH_HEAD
}

Що таке gd2? Якийсь псевдонім git diff?
заарештований

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