如何生成自上次拉动以来发生的更改的git diff?


76

我想将以下操作编写为一个命令,最好是在rake中编写脚本:

  1. 获取本地git存储库的版本。
  2. Git拉最新的代码。
  3. 从我在步骤1中提取的版本到现在本地存储库中的版本的diff。

换句话说,我想从中央存储库中获取最新代码,并立即生成自上次提取以来所发生更改的差异。

Answers:


91

您可以使用refspec相当简单地做到这一点。

git pull origin
git diff @{1}..

这将使您对分支之前和之后存在的当前分支有所不同。请注意,如果pull并没有实际更新当前分支,则diff将为您提供错误的结果。另一个选择是显式记录当前版本:

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

我个人使用的别名只是以反向顺序(即从最旧到最新)向我显示自上次拉取以来所有提交的日志(无顺序)。每当我的pull更新分支时,我都会运行此命令:

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

1
@leemes:嗯?git diff HEAD将显示HEAD和当前工作副本之间的更改。这不是特富龙·特德想要的。
莉莉·巴拉德

抱歉,我误解了这个问题。自上次我将飞机降落在这里以来,我一直在寻找一条命令来显示我的更改。git diff HEAD为我需要的工作(至少我想这是我在寻找的:D)
leemes 2012年

4
有人可以解释(或告诉我在何处阅读)@{1}..确切的含义吗?只是将其扔进Google并没有帮助。
user1129682

5
@ user1129682:这是访问reflog的语法。如果没有分支名称,则意味着访问当前分支的引用日志。值的@{1}意思是最新的引用日志条目,例如,当前分支在指向当前提交之前所指向的内容。
莉莉·巴拉德

2
+1,这是正确的方法。您应该在@{1}..符号上进行一些扩展,也许将默认值明确地放在此处,然后显示紧凑版本,所以它的魔力就不那么大了。
slezica 2014年

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更改Git遥控器的URL 。有区别吗?我不知道,但是看来这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

之后,agit pull会将更改合并到您的HEAD中。


我没有将origin定义为git-diff或git-rev-parse的特殊关键字。您是否意味着我需要插入步骤1中的哈希值作为origin的值?如果是这样,我如何以编程方式提取该值?为了方便起见,我想将所有这些步骤组合到一个命令/脚本中。
铁氟龙泰德

2
执行此操作的另一种方法是使用特殊的FETCH_HEAD头,该头反映了先前提取的结果。因此:“ git fetch && git diff ... FETCH_HEAD”。
格雷格·休吉尔

我认为这是更合适的响应:git fetch紧随其后的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的某种别名?
2012年

这是在上一个脚本中parse_git_branch之后定义的bash函数
Clintm'2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.