我配置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}})。
答案 0 :(得分:1)
好的,根据评论,请注意:
pull
脚本与 1 git fetch
基本相同,后跟git merge
或git rebase
,具体取决于您要求的那个(在您的配置设置中或使用--rebase
)。gitrevisions
语法,我们可以找到"提交一些分支名称,如master
,在rebase运行之前指向"与master@{1}
。 (git reflog
documentation中详细描述了reflog语法。)因此,您可以使用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_HEAD
,FETCH_HEAD
,HEAD
等,但它在每一行都有一些额外的信息,专门用于MERGE_HEAD
脚本。
在所有情况下,ORIG_HEAD
引入新提交和可能更新远程分支后,pull
脚本会从fetch
中提取最新提交的SHA-1 ID 。它将此原始SHA-1 ID提供给pull
或FETCH_HEAD
。
还有一个特例:当merge
要进行rebase时,它有一些奇特的逻辑来检测和恢复远程的rebase。通常这不应该发生(撤消已发布/共享提交不是一个好主意),但rebase
可以处理它,而常规git pull
需要用户提供额外帮助。 (git 1.9 / 2.0中有一个新功能可以让这项功能更好。)
我认为值得一看git pull --rebase
(如果这是您的git rebase
目录所在的位置:有时它是/usr/local/libexec/git-core/git-pull
而不是其他地方)看看它是如何工作的。