简体   繁体   English

有没有一种从点或分支原点“git diff”的快速方法?

[英]Is there a quick way to "git diff" from the point or branch origin?

I have looked at various SO answers on using git diff and git revisions (HEAD, ORIG_HEAD, FETCH_HEAD, etc.) and I still haven't found an easy way to list the changes have been made since the beginning of the local branch, or since last rebase.我已经查看了关于使用git diff和 git 修订版(HEAD、ORIG_HEAD、FETCH_HEAD 等)的各种 SO 答案,但我仍然没有找到一种简单的方法来列出自本地分支开始以来所做的更改,或者自上次变基以来。

By easy I mean without having to look up and paste commit SHA or having to count how many commits I want to look back.我所说的简单是指无需查找和粘贴提交 SHA,也不必计算我想回顾的提交数量。

git diff origin/master is close, but it refers to remote which may have diverged since I checked out new branch from it. git diff origin/master很接近,但它指的是 remote,自从我从中签出新分支以来它可能已经发散。

I would expect something like git diff BASE_HEAD to be available.我希望像git diff BASE_HEAD这样的东西可用。

...unless there's already a way to do that. ...除非已经有办法做到这一点。 Does anyone have the answer?有人知道答案吗?

You can find the branch point using git merge-base .您可以使用git merge-base找到分支点 Consider master the mainline and dev the branch whose history you are interested in. To find the point at which dev was branched from master , run:考虑master主线和dev分支你感兴趣的历史。要找到devmaster分支的点,运行:

git merge-base --fork-point master dev

We can now diff dev against this basis:我们现在可以在此基础上对dev进行差异化:

git diff $(git merge-base --fork-point master dev)..dev

If dev is the current branch this simplifies to:如果dev当前分支,则简化为:

git diff $(git merge-base --fork-point master)

For more information see the git-merge-base documentation .有关更多信息,请参阅git-merge-base文档

Use git diff @{u}...HEAD , with three dots.使用git diff @{u}...HEAD ,带三个点。

With two dots, or with HEAD omitted, it will show diffs from changes on both sides.使用两个点或省略HEAD ,它将显示两侧变化的差异。

With three dots, it will only show diffs from changes on your side.三个点,它只会显示与您这边的变化的差异。

Edit: for people with slightly different needs, you might be interested in git merge-base (note that it has plenty more options than the other answer uses).编辑:对于需求略有不同的人,您可能对git merge-base感兴趣(请注意,它比其他答案使用的选项多得多)。

You can diff the current branch from the branch start point using:您可以使用以下方法从分支起点区分当前分支:

git diff (start point)...

Where (start point) is a branch name, a commit-id, or a tag.其中(起点)是分支名称、提交 ID 或标签。

Eg if you're working on a feature branch branched from develop , you can use:例如,如果您正在处理从develop分支的功能分支,则可以使用:

git diff develop...

for all changes on the current branch since the branch point.自分支点以来当前分支上的所有更改。

This was already mentioned in a comment, but I think it deserves answer status.这已经在评论中提到了,但我认为它值得回答。 I don't know what it will do since last rebase.我不知道自上次 rebase 以来它会做什么。

For diffs, you want the three-dot notation.对于差异,您需要三点符号。 If your branch is called dev and it branched from master :如果您的分支名为dev并且它从master分支:

% git diff master...dev

For log, you want the two-dot notation:对于日志,您需要两点表示法:

% git log master..dev

The revision syntax r1..r2 (with two dots) means "everything reachable from r2 (inclusive) but not reachable from r1 (inclusive)".修订语法r1..r2 (带两个点)表示“所有可从r2 (包含)到达但无法从r1 (包含)到达”。 The normal way to use this is to think of r1 and r2 as specifying a range in a sequence of commits ( r1 exclusive, r2 inclusive), so if you have 10 revisions, 3..7 will show you changes 4, 5, 6, and 7. It's {1, 2, 3, 4, 5, 6, 7} minus {1, 2, 3} .使用它的正常方法是将r1r2视为在提交序列中指定一个范围(不包括r1 ,包括r2 ),因此如果您有 10 个修订版, 3..7将显示更改 4、5、6 , 和 7. 它是{1, 2, 3, 4, 5, 6, 7}减去{1, 2, 3} But r1 doesn't necessarily have to be an ancestor of r2 .但是r1不一定是r2的祖先。 Think of it more like a set operation where r1 represents the entire ancestry from r1 backwards, and r2 represents the entire ancestry from r2 backwards, and you're subtracting the first set from the second set.把它想象成一个集合操作,其中r1代表从r1向后的整个祖先,而r2代表从r2向后的整个祖先,你从第二个集合中减去第一个集合。

So then:那么:

git log master..dev

is the entire history of the branch minus the entire history of master.是分支的整个历史减去 master 的整个历史。 In other words, just the branch.换句话说,只是分支。

The current solution mentions当前的解决方案提到

Use git diff @{u}...HEAD , with three dots.使用git diff @{u}...HEAD ,带三个点。

But... this is best done with Git 2.28 (Q3 2020).但是……这最好使用 Git 2.28(2020 年第三季度)来完成。
Before, " git diff " used to take arguments in random and nonsense range notation, eg " git diff A..BC ", " git diff A..B C...D ", etc., which has been cleaned up.之前,“ git diff ”过去常常采用随机和无意义范围表示法的参数,例如“ git diff A..BC ”、“ git diff A..B C...D ”等,这些已经被清理干净了。

See commit b7e10b2 , commit 8bfcb3a (12 Jun 2020), and commit bafa2d7 (09 Jun 2020) by Chris Torek ( chris3torek ) .请参阅Chris Torek ( chris3torek ) 的commit b7e10b2commit 8bfcb3a (2020 年 6 月 12 日)和bafa2d7 (2020 年 6 月 9 chris3torek
(Merged by Junio C Hamano -- gitster -- in commit 1457886 , 25 Jun 2020) (由Junio C gitster合并-- gitster -- in commit 1457886 ,2020 年 6 月 25 日)

git diff : improve range handling git diff :改进范围处理

Signed-off-by: Chris Torek签字人:Chris Torek

When git diff is given a symmetric difference A...B , it chooses some merge base from the two specified commits (as documented).git diff被赋予对称差异A...B ,它会从两个指定的提交中选择一些合并基础(如文档所述)。

This fails, however, if there is no merge base: instead, you see the differences between A and B, which is certainly not what is expected.但是,如果没有合并基础,这将失败:相反,您会看到 A 和 B 之间的差异,这肯定不是预期的。

Moreover, if additional revisions are specified on the command line (" git diff A...BC "), the results get a bit weird:此外,如果在命令行上指定了其他修订(“ git diff A...BC ”),结果会变得有点奇怪:

  • If there is a symmetric difference merge base, this is used as the left side of the diff.如果存在对称差异合并基,则将其用作差异的左侧。
    The last final ref is used as the right side.最后一个最终参考用作右侧。

  • If there is no merge base, the symmetric status is completely lost.如果没有合并基,则对称状态完全丢失。
    We will produce a combined diff instead.我们将生成一个组合差异。

Similar weirdness occurs if you use, eg, " git diff C A...BD ".如果您使用例如“ git diff C A...BD ”,则会发生类似的怪异现象。 Likewise, using multiple two-dot ranges, or tossing extra revision specifiers into the command line with two-dot ranges, or mixing two and three dot ranges, all produce nonsense.同样,使用多个两点范围,或将额外的修订说明符投入具有两点范围的命令行,或混合两个和三个点范围,都会产生废话。

To avoid all this, add a routine to catch the range cases and verify that that the arguments make sense.为了避免这一切,添加一个例程来捕获范围情况并验证参数是否有意义。

As a side effect, produce a warning showing which merge base is being used when there are multiple choices;作为副作用,当有多个选择时,会产生一个警告,显示正在使用哪个合并基础; die if there is no merge base.如果没有合并基础,则死亡。

The documentation now includes: 该文档现在包括:

'git diff' [<options>] <commit> [<commit>...] <commit> [--] [<path>...] : 'git diff' [<options>] <commit> [<commit>...] <commit> [--] [<path>...] :

This form is to view the results of a merge commit.此表单用于查看合并提交的结果。

The first listed must be the merge itself;列出的第一个必须是合并本身; the remaining two or more commits should be its parents.剩下的两个或更多提交应该是它的父母。
A convenient way to produce the desired set of revisions is to use the {caret}@ suffix.生成所需修订集的一种便捷方法是使用{caret}@后缀。
For instance, if master names a merge commit, git diff master master^@ gives the same combined diff as git show master .例如,如果master命名合并提交,则git diff master master^@给出与git show master相同的组合差异。

If you use a newer git version, you can simply use如果你使用较新的 git 版本,你可以简单地使用

git diff --merge-base <target_branch>

Which delivers (for me) identical results to currently highest voted answer of:这为我提供了与当前投票最高的答案相同的结果:

git diff $(git merge-base --fork-point origin/main)

The command was introduced in Git Version 2.30 as:该命令在Git 版本 2.30中引入为:

"git diff A...B" learned "git diff --merge-base AB", which is a longer short-hand to say the same thing. “git diff A...B”学习了“git diff --merge-base AB”,这是表达相同内容的更长的简写形式。

So basically it another way of gettings the same result as the currently accepted answer .所以基本上它是另一种获得与当前接受的答案相同结果的方法。

要与远程主分支进行比较:

git diff $(git merge-base HEAD origin/master)..

I wrote an alias in my .gitconfig to solve this task:我在我的.gitconfig写了一个别名来解决这个任务:

[alias]
    # See changes since branching off of main branch
    changes = "!f() { \
        current=$(git rev-parse --abbrev-ref HEAD); \
        main=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'); \
        commit=$(git merge-base --fork-point \"$main\" \"$current\"); \
        git diff \"$commit\"...; \
    }; f"

Line-by-line, this alias:逐行,这个别名:

  1. Defines a shell function, f , which定义一个壳函数f ,它
  2. computes the current branch name,计算当前分支名称,
  3. computes the main branch name (which could be main, master, develop, etc.),计算主分支名称(可以是 main、master、develop 等),
  4. computes the commit from which these two branches diverge, and计算这两个分支发散的提交,和
  5. runs git diff to see the changes since this commit运行git diff以查看自此提交以来的更改

In Visual Studio 2017 there is a comfortable way to show diffs:在 Visual Studio 2017 中,有一种舒适的方式来显示差异:

  1. In Team Explorer -> Branches right click the branch and select View History团队资源管理器 -> 分支中右键单击分支并选择查看历史记录

查看历史

  1. In the History - branch control select the commits you want the diff and select Compare Commits历史记录 - 分支控件中选择您想要差异的提交并选择比较提交

比较提交

You get a nice diff overview and you can open the files in compare mode.你会得到一个很好的差异概述,你可以在比较模式下打开文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM