查看自拉动后最后一次更改后的更改差异

时间:2014-03-07 22:20:02

标签: git

我配置git pull进行rebase。另外,我还在我的配置中启用了rebase.stat,这样我就能看到在我的分支中引入了哪些新的更改:

$ git pull
 .../zMovie/Source/FormManagers/FrmHome.cpp         | 105 +++++++++------------
 .../zMovie/Source/FormManagers/FrmTheater.cpp      |  26 ++++-
 .../zMovie/Source/FormManagers/FrmTheater.h        |   2 +-
 3 files changed, 72 insertions(+), 61 deletions(-)
First, rewinding head to replay your work on top of it...

我在这里遇到的问题是Git似乎缩短了更新文件的路径,所以我不能简单地复制/粘贴它们来查看它们的各个差异。通常我喜欢比较文件中的更改内容:

$ git diff master~ master -- .../zMovie/Source/FormManagers/FrmHome.cpp

但是,由于我没有文件的完整路径(当然相对于repo根目录),因此上述操作无效。它省略了路径的顶层,以使其足够短以显示它所显示的列。

如果来自git pull的输出显示了来自master的修订范围,我也很高兴新的更改来自git diff,这样我就可以difftool在该范围内,但我没有在输出中得到它。

有没有办法改善我的工作流程?我真的只想查看自master分支上最后一个rebase以来引入的新变化的差异(最好是{{1}})。

1 个答案:

答案 0 :(得分:1)

好的,根据评论,请注意:

  1. pull脚本与 1 git fetch基本相同,后跟git mergegit rebase,具体取决于您要求的那个(在您的配置设置中或使用--rebase)。
  2. 使用gitrevisions语法,我们可以找到"提交一些分支名称,如master,在rebase运行之前指向"与master@{1}。 (git reflog documentation中详细描述了reflog语法。)
  3. 因此,您可以使用git diff branch@{1} branch查看rebase对您的代码所做的操作(注意:在某些shell中,不包括bash但包括csh / tcsh,您必须引用大括号才能使其工作:{例如{1}}或git diff 'branch@{1}' branch

    (你可以得到更好的:gitrevisions语法可以在任何地方使用,所以你可以使用它们作为git merge-base的参数。)


    下面是长插图,随意跳过。

    在fetch-and-rebase之前,您可能会遇到以下情况:

    git diff branch@\{1} branch

    o--o--o <-- master / c--c--c <-- origin/master 提交节点是&#34;常见&#34; (您和其他人共享),而c提交节点是&#34;我们的&#34; (或&#34;原创&#34;),即你自己的作品,尚未与任何人分享。

    当你o这会带来新的工作时,让我们称他们为fetch,同时也是新的:

    C

    (见脚注1的小警告)。此时 o--o--o <-- master / c--c--c--C--C <-- origin/master 没有发生任何事情,但是当你指示时,拉动master。这会将您的git rebase提交复制到新的,稍有不同的提交中(它们现在包含o提交中已更改的内容):

    C

    三个原始提交( o--o--o <-- master@{1} / c--c--c--C--C <-- origin/master \ *--*--* <-- master )仍在那里。通常情况下,它们是不可见的:我将它们贴上标签&#34;放弃&#34;在其他StackOverflow答案的类似图纸中,因为它们没有指向它们的分支名称。然而,reflog保留了以前的参考文献&#34;活了一会儿(默认= 30天),o@{1}或其他类似的语法可以用来挖掘它们。

    因此,@{yesterday}会将最后一次git diff master@{1} master提交与最后一次o提交进行比较,该提交会向您显示他们的工作方式&#34;影响&#34;你做了什么&#34;。

    (请注意,* 有一个reflog。如果您定期origin/master,以便更新fetch,您可以{{1}将最后一次origin/master提交与第二次git diff origin/master@{1} origin/master提交进行比较。但是,如果您使用c,则需要git 1.8.4或更新才能更新C;请参阅脚注1。)


    1 git pull确实运行origin/master时,它确实会直接调用git pull origin master。这里的事情是它提供git fetch origin master 两个参数:远程和分支名称。在早于1.8.4的git版本中,这会改变git fetch的运行方式,因此fetch 不会更新fetch。在1.8.4及更新版本中,fetch更新了远程分支origin/master,这更有意义:现在,#34;我们的git&#34;知道&#34;他们的git&#34;有新的提交,我们真的应该更新我们在那里fetch的位置的想法。 (那是一个&#34;远程分支&#34;是:本地副本,&#34;他们的&#34;分支是,我们最后一次检查。)

    origin/master命令始终将获取的分支信息写入顶级git目录中的文件master。它无论如何被调用都会这样做。虽然fetch看起来很像常规参考la FETCH_HEADFETCH_HEADHEAD等,但它在每一行都有一些额外的信息,专门用于MERGE_HEAD脚本。

    在所有情况下,ORIG_HEAD引入新提交和可能更新远程分支后,pull脚本会从fetch中提取最新提交的SHA-1 ID 。它将此原始SHA-1 ID提供给pullFETCH_HEAD

    还有一个特例:当merge要进行rebase时,它有一些奇特的逻辑来检测和恢复远程的rebase。通常这不应该发生(撤消已发布/共享提交不是一个好主意),但rebase可以处理它,而常规git pull需要用户提供额外帮助。 (git 1.9 / 2.0中有一个新功能可以让这项功能更好。)

    我认为值得一看git pull --rebase(如果这是您的git rebase目录所在的位置:有时它是/usr/local/libexec/git-core/git-pull而不是其他地方)看看它是如何工作的。