使用Git可视化工具展示分支拓扑结构

1087

我在自己的机器上独立使用Git,发现很难保持对所有分支和提交的心理模型。我知道可以使用git log查看从当前位置开始的提交历史记录,但是否有一种方法可以查看整个分支拓扑结构,类似于这些似乎被用于解释分支的ASCII地图?

      .-A---M---N---O---P
     /     /   /   /   /
    I     B   C   D   E
     \   /   /   /   /
      `-------------'

我觉得如果有人想要接手我的代码库,他们可能会很难理解其中的细节。

我想我受到了 AccuRev 的 stream browser 的影响...


无法在终端中显示Git树 - Leif Gruenwoldt
1
@leif81,对我来说是半重复。@Masi在他的问题中明确排除了gitk。 - Benjol
这个回答解决了你的问题吗?Pretty git branch graphs - Gonçalo Peres
33个回答

1315

使用git log --graph或者gitk命令。(两者都支持--all参数,它会显示所有的分支而不只是当前分支。)

如果想要查看分支名称和精简视图,请尝试:

git log --graph --decorate --oneline

55
这甚至没有用分支标记提交。就现在而言,我不会认为这是一个好的可视化。 - Roman Starkov
9
谢谢!gitg也有“--all”选项,并且也标记了提交。我在下拉列表中也从未看到可以选择所有分支的选项。 - Thomas
230
我建议使用git log --graph --decorate --oneline命令,它会将每个提交显示在一行上,并用分支名称进行修饰。 - sleske
9
tig(一个基于ncurse的git客户端)还提供了“--all”选项,非常方便! - Pierre-Adrien
6
请参考Andrew的回答(//stackoverflow.com/questions/1838873/visualizing-branch-topology-in-git#answer-7509303),了解有关--simplify-by-decoration选项的信息。 - ruvim
显示剩余6条评论

624

我有3个别名 (和4个替代快速使用的别名) ,通常放在我的~/.gitconfig文件中:

[alias]
    lg = lg1
    lg1 = lg1-specific --all
    lg2 = lg2-specific --all
    lg3 = lg3-specific --all

    lg1-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)'
    lg2-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
    lg3-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset) %C(bold cyan)(committed: %cD)%C(reset) %C(auto)%d%C(reset)%n''          %C(white)%s%C(reset)%n''          %C(dim white)- %an <%ae> %C(reset) %C(dim white)(committer: %cn <%ce>)%C(reset)'

git lg/git lg1 这样显示:

git lg1

git lg2 显示为:

git lg2

git lg3 显示为:

git lg3

需要注意的是,这并不是一个通用解决方案——它只是一个模板,供您根据自己的喜好进行更改、添加和修复。如果您想使用这些模板,我建议您:

  1. 将它们添加到您的.gitconfig文件中,
  2. 对其进行个性化定制(不同的颜色选择,2-和3行版本的不同行排列等),
  3. 然后将其保存到Gist或其他代码片段工具中,以便将来将其复制粘贴到.gitconfig(或者当然也可以通过版本控制保存您的点文件).

注意:答案来源于stackoverflow.com/questions/1057564/pretty-git-branch-graphs的答案,并进行了改进,因为在这里比那里更合适。在其他问题中保留副本,供历史原因使用——现在已关闭,并且该答案被其他答案引用。


22
建议:将%C(bold yellow)替换为%C(auto),以便在HEAD本地分支远程分支之间使用不同的颜色。(参考链接:https://dev59.com/X2cs5IYBdhLWcg3woFft) - Atcold
3
注意,你可以使用%w()来避免在格式化字符串中手动添加缩进;这样做可以确保更好地换行较长或多行的提交信息而不会破坏图形。 - charliegreen
2
@mbadawi23 为了保持平台和 Git 安装的一致性,它们是冗余的。--abbrev-commit 在其中是因为第二至第三行是手动缩进的空格,我想确保它使用短 SHA,所以安全第一。--decorate 也在其中,因为虽然 Git 的默认设置做同样的事情,但可能会在不同的 Git 版本中进行配置或有所不同,对于这些情况,我绝对需要修饰。最终,在这里使用额外/冗余的标志并不是坏事——这将放入文件中;这不是你经常键入的内容。 - Slipp D. Thompson
2
@TimothyPulliam 要理解哪些提交是“每个分支的一部分”,您必须直观地跟踪彩色线条。几乎所有工具都无法帮助您完成此操作,因为Git提交不属于任何分支 - 它们被暗示(在图形可视化时)属于具有它们在其父级祖先中的任何分支或标记。如果没有引用提交的分支/标记并且它消失了(但大约两周后不会被垃圾回收),请添加引用先前未引用的提交的分支/标记,然后它将重新出现。我希望这一切都说得通。 - Slipp D. Thompson
3
@PedroGarcíaMedina 我的意思是“将这个引用文本作为 shell 命令运行,而不是调用另一个 git 命令”,主要是为了将其他工具与 git 集成 _(例如,你可以编写类似于 syncup =!“git pull && make all” 的内容)_。我在这里使用它,因为我无法在别名中调用另一个别名(我只能调用 git 命令),但也许在较新版本的 git 中已经改变了。我会再次检查并简化,如果现在只需要 lg = lg1 就可以完成的话。 - Slipp D. Thompson
显示剩余17条评论

530

我通常使用

git log --graph --full-history --all --pretty=format:"%h%x09%d%x20%s"

如果你的shell是Bash,可以使用颜色:

git log --graph --full-history --all --color \
        --pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s"

这将打印出类似于文本的表示形式:

* 040cc7c       (HEAD, master) Manual is NOT built by default
* a29ceb7       Removed offensive binary file that was compiled on my machine and was hence incompatible with other machines.
| * 901c7dd     (cvc3) cvc3 now configured before building
| * d9e8b5e     More sane Yices SMT solver caller
| | * 5b98a10   (nullvars) All uninitialized variables get zero inits
| |/
| * 1cad874     CFLAGS for cvc3 to work successfully
| *   1579581   Merge branch 'llvm-inv' into cvc3
| |\
| | * a9a246b   nostaticalias option
| | * 73b91cc   Comment about aliases.
| | * 001b20a   Prints number of iteration and node.
| |/
|/|
| * 39d2638     Included header files to cvc3 sources
| * 266023b     Added cvc3 to blast infrastructure.
| * ac9eb10     Initial sources of cvc3-1.5
|/
* d642f88       Option -aliasstat, by default stats are suppressed

你可以使用 git log --format=oneline 命令,但这会将提交信息和数字联系在一起,我认为不够美观。

如果要为此命令创建快捷方式,您可能需要编辑您的 ~/.gitconfig 文件:

[alias]
  gr = log --graph --full-history --all --color --pretty=tformat:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s%x20%x1b[33m(%an)%x1b[0m"
然而,正如Sodel the Vociferous在评论中指出的那样,这样的长格式命令很难记忆。通常情况下,这并不是问题,因为您可以将其放入~/.gitconfig文件中。但是,如果您有时需要登录到无法修改配置文件的远程机器,则可以使用更简单但打字速度更快的版本:
git log --graph --oneline

12
如果您喜欢日期:git log --graph --full-history --all --color --date=short --pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%ad %s" - sehugg
7
“oneline”是一个更易记的替代品,用于取代那些漂亮的格式深度魔法。 - Daniel Ralston
1
@SodeltheVociferous,确实,我没有从你谈论的那个角度来解决问题;我扩展了我的答案。 - P Shved
2
注意:仅在使用“--simplify-by-decoration”或指定文件路径时,“--full-history”才是相关的。 - Slipp D. Thompson
2
我可以问一下你从哪里得到了这个格式字符串吗?或者你是如何想出那个东西的? - elliotwesoff
1
如果您仍然在两年后疑惑,可以查看git log文档中的“PRETTY FORMATS”部分,在“format: <string>”项下方稍微往下滚动。 - Andrew Spencer

288

对于这些基于git log或gitk的记录,您可以添加--simplify-by-decoration来折叠历史中无趣的线性部分。这样可以一次显示更多拓扑结构。有了这个选项,我现在能够理解那些如果没有它就难以理解的大型历史记录了!

我觉得有必要发布这篇文章,因为它似乎并不像应该那样广为人知。它在大多数关于可视化历史的Stack Overflow问题中都没有出现,并且即使在我知道我想要它之后,我还是搜索了相当长的时间才找到它!我最终在这个Debian bug报告中找到了它的信息。在Stack Overflow上的首次提及似乎是Antoine Pelisse的这个回答。


7
完美 -- 正是我在寻找的!它应该得到更多的赞同票;几乎每个人都已经知道gitk/gitg/git log --graph,但如果您想可视化分支拓扑结构并且不关心单个提交,这些工具并不是非常有用。 - imolit
8
这正是我所需要的,太棒了。在所有答案中,只有它帮助了我。--simplify-by-decoration非常清晰地解释了正在发生的事情。 - Ela782
14
这应该是正确的答案。git log --graph --all --simplify-by-decoration 也可以起到同样的作用。 - Irfy
1
如果我们能在每个装饰提交之前/之后添加n个提交时使用--simplify-by-decoration(就像对于grep-B-A一样),那该多好啊。 - junvar
1
我使用这个解决方案非常频繁,我已经将其别名为“git tree”。 - user16973

82

Gitk 的输出有时对我来说很难读懂:

在这里输入图片描述

这促使我写了 GitVersionTree

在这里输入图片描述


4
我已向作者提交了一份支持Mono的PR(已在Ubuntu 13.10上测试,与Mono 2.10兼容)。 - Max Ehrlich
1
我发现GitVersionTree会将分支保留在同一位置,这使得更容易看到事物的变化。 - sfranky
2
刚刚偶然发现这个,看起来真的很酷;我迫不及待地想试试。有一个建议(也许你已经有了),但是折叠多个不分叉点的提交可能会很好。这将使查看分支拓扑更容易。 - Edward Falk

61
请看一下GitKraken - 这是一个跨平台图形用户界面,以清晰的方式显示拓扑结构。

Topology

这里有一个关于一些高级功能的视频教程

注意:需要注册。


13
为什么这个帖子有GitKraken,但没有老而免费的SourceTree?(我知道,我知道,Atlassian并不总是做得完美。但SourceTree是一个非常好的可视化工具。) - XML
@XML在Linux上不可用。 - imashnake_
同一家公司还开发了一款 Visual Studio Code 扩展名叫做 GitLens。它是免费的,甚至不需要注册。 - Fabio says Reinstate Monica

53

我花99.999%的时间用git lg 查看历史记录,而只有0.001%的时间使用 git log

我想分享两个可能有用的日志别名(从.gitconfig进行配置):

[Alias]
     lg = log --graph --pretty=format:'%Cred%h%Creset %ad %s %C(yellow)%d%Creset %C(bold blue)<%an>%Creset' --date=short
     hist = log --graph --full-history --all --pretty=format:'%Cred%h%Creset %ad %s %C(yellow)%d%Creset %C(bold blue)<%an>%Creset' --date=short
  • git lg将查看当前分支的历史记录。
  • git hist将查看整个分支的历史记录。

45

我喜欢用git log来做:

 git log --graph --oneline --branches

(同时也可以使用 --all,以查看远程分支)

与最近的 Git 发布版本兼容:自 1.6.32009年5月7日)引入

  • 日志命令族的 "--pretty=<style>" 选项现在可以拼写为 "--format=<style>"。
    此外,--format=%formatstring--pretty=tformat:%formatstring 的简写。

  • "--oneline" 是 "--pretty=oneline --abbrev-commit" 的同义词。

PS D:\git\tests\finalRepo> git log --graph --oneline --branches --all
* 4919b68 a second bug10 fix
* 3469e13 a first bug10 fix
* dbcc7aa a first legacy evolution
| * 55aac85 another main evol
| | * 47e6ee1 a second bug10 fix
| | * 8183707 a first bug10 fix
| |/
| * e727105 a second evol for 2.0
| * 473d44e a main evol
|/
* b68c1f5 first evol, for making 1.0

您还可以限制日志显示的范围(提交数量):

PS D:\git\tests\finalRepo> git log --graph --oneline --branches --all -5
* 4919b68 a second bug10 fix
* 3469e13 a first bug10 fix
* dbcc7aa a first legacy evolution
| * 55aac85 another main evol
| | * 47e6ee1 a second bug10 fix

(仅显示最近的5个提交)


我不喜欢当前选择的解决方案的原因是:
 git log --graph

当我只想看快速概要时,它显示了太多信息:

PS D:\git\tests\finalRepo> git log --graph
* commit 4919b681db93df82ead7ba6190eca6a49a9d82e7
| Author: VonC <vonc@laposte.net>
| Date:   Sat Nov 14 13:42:20 2009 +0100
|
|     a second bug10 fix
|
* commit 3469e13f8d0fadeac5fcb6f388aca69497fd08a9
| Author: VonC <vonc@laposte.net>
| Date:   Sat Nov 14 13:41:50 2009 +0100
|
|     a first bug10 fix
|

gitk很棒,但它会迫使我离开shell会话去打开另一个窗口,而快速显示最近的n个提交通常已经足够了。


我也选择了这种方法,不过我建立了一个别名,这样输入“git graph”就相当于执行“git log --graph --decorate --oneline”。 - Will Pike
@ConnerPike 好主意。我自己也有别名“lg”:请参见https://dev59.com/L3A65IYBdhLWcg3wuhIR#3667139 - VonC

41

Gitg是类似于OS X上的Gitx的Linux中一个非常好用的工具。只需在存储库目录树结构内的某个地方从命令行输入“gitg”(与gitx相同)即可。


3
简而言之,gitg有一个下拉菜单,可以选择要可视化的分支。此下拉菜单还有一个“全部”选项。 - Phluks
1
或者您可以使用 gitg --all 命令来启动它,如果您想避免在下拉菜单中瞎搞的话。 - imolit

29
一个不错的基于web的工具是ungit。它可以在任何支持Node.js和Git的平台上运行。有一个视频展示了它的工作方式,对于那些觉得通过观看比阅读更容易理解的人来说可能会更有帮助。。。

这里输入图片描述


我正在使用它。在小项目上运行良好 - 当分支不太多时。不幸的是,当有20-50个打开的分支时,它无法使用。 - Anton Prokofiev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接