The Git interface you've been missing all your life has finally arrived.
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 7 个月前 | ||
| 2 年前 | ||
| 7 年前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 7 年前 | ||
| 1 年前 | ||
| 6 年前 | ||
| 4 年前 | ||
| 8 年前 | ||
| 5 年前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 7 个月前 | ||
| 4 年前 | ||
| 2 年前 |
快速、安全、无烦恼地工作。你一直苦苦寻觅的 Git 界面终于来了。
Git 最近刚庆祝了它的 10 周年,但大多数工程师仍然对其复杂性感到困惑(Stack Overflow 上历来投票最高的 5 个问题中就有 3 个与 Git 相关)。由于 Git 能将简单操作都变成令人费解的命令(比如用“git add”暂存,却要用“git reset HEAD”取消暂存,这谁懂啊?),难怪用户会浪费时间、感到沮丧、不得不打扰团队其他人寻求帮助,更糟的是,还可能搞乱自己的代码库!
GitUp 旨在开创一种全新的 Git 交互模式,让各个层级的工程师都能快速、安全、无烦恼地工作。无论是其构建方式(直接与磁盘上的 Git 数据库交互),还是其工作方式(直接操作仓库图谱而非提交记录),都与市面上其他 Git 客户端截然不同。
有了 GitUp,你将获得一款真正高效的 Mac Git 客户端:
- 实时交互式仓库图谱(编辑、重排、修正、合并提交……),
- 几乎所有操作都支持无限撤销/重做(甚至包括变基和合并),
- 类似 Time Machine 的快照功能,一键回滚到仓库之前的状态,
- 一些 Git 原生并不存在的功能,例如可视化提交拆分器和统一的引用日志浏览器,
- 即时搜索整个仓库,包括差异内容,
- 快得离谱的用户界面,通常比命令行还要快。
此外,GitUp 的核心和主要 UI 元素作为开源框架 GitUpKit 提供。你可以用它来构建自己的 Git GUI!GitUpKit 已经催生出了一些独特的应用:
Retcon**,**一款让重写历史记录变得快速且灵活的 Git 客户端
GitUp 由 @swisspol 于 2014 年底创建,旨在重新定义开发者与 Git 的交互方式。经过数月的开发,它于 2015 年初发布预览版,并登上了 Hacker News 榜首,同时被 Product Hunt 和 Daring Fireball 专题报道。在编写了 30,000 行代码后,GitUp 于 2015 年 8 月中旬迎来 1.0 版本,并作为给开发者社区的礼物开源发布。
入门指南
- 官方网站:https://gitup.co
下载方式:
- GitHub 最新发布版本:https://github.com/git-up/GitUp/releases
- Homebrew(非 GitUp 开发者维护):
brew install gitup-app
请阅读 文档,并通过 GitHub Issues 获取支持和提供反馈。
发布说明可在 https://github.com/git-up/GitUp/releases 查看。标记为 v 的版本(例如 v1.2.3)发布在“稳定版”通道,而标记为 b 的版本(例如 b1234)仅发布在“持续版”通道。您可以在应用偏好设置中更改 GitUp 使用的更新通道。
构建
若要自行构建 GitUp,只需在终端中运行命令 git clone --recursive https://github.com/git-up/GitUp.git,然后打开 GitUp/GitUp.xcodeproj Xcode 项目并点击“运行”。
重要提示: 如果您没有用于 Mac 应用代码签名的开发者账户 Apple ID,构建将因代码签名错误而失败。只需删除“Application”目标的“Code Signing Identity”构建设置即可解决此问题:
或者,如果您有开发者账户,可以创建文件“Xcode-Configurations/DEVELOPMENT_TEAM.xcconfig”,并在其中添加以下构建设置内容:
DEVELOPMENT_TEAM = [您的 TeamID]
有关详细说明,您可以查看文件“Xcode-Configurations/Base.xcconfig”末尾的注释。
GitUpKit
GitUp 构建于一个名为“GitUpKit”的可复用通用 Git 工具包之上,自身仅作为一层轻量封装。这意味着您也可以使用同一个 GitUpKit 框架来构建您自己的 Git UI!
GitUpKit 的目标与 ObjectiveGit 有很大不同。它并非提供对 libgit2 的全面原始绑定,而是仅使用 libgit2 的最小子集,并在此基础上重新实现了其他所有功能(例如,它拥有自己的“变基引擎”)。 这使得它能够提供一套紧密且一致的 API,完全遵循 Objective-C 约定,并隐藏了 libgit2 的复杂性及偶尔出现的不一致性。此外,GitUpKit 还添加了许多独特而强大的功能,从撤销/重做、类 Time Machine 快照,到完整的即插即用 UI 组件。
架构
GitUpKit 源代码分为两个独立层,仅通过公共 API 进行通信:
基础层(仅依赖 Foundation,兼容 OS X 和 iOS)
Core/:对 libgit2 所需最小功能的封装,GitUp 所需的所有 Git 功能均在此基础上实现(请注意,GitUp 使用 经过略微定制的 libgit2 分支)Extensions/:Core类的分类,用于添加仅使用公共 API 实现的便捷功能
UI 层(依赖 AppKit,仅兼容 OS X)
Interface/:低级视图类,例如用于渲染 GitUp 地图视图的GIGraphViewUtilities/:界面工具类,例如基础视图控制器类GIViewControllerComponents/:可重用的单视图视图控制器,例如用于渲染差异的GIDiffContentsViewControllerViews/:高级可重用多视图视图控制器,例如用于实现整个 GitUp 高级提交视图的GIAdvancedCommitViewController
重要提示:如果在构建 GitUpKit 时将预处理器常量 DEBUG 定义为非零值(这是“Debug”配置下构建的默认设置),则会在运行时启用大量额外的一致性检查以及额外的日志记录。请注意,此开销可能会显著影响性能。
GitUpKit API
GitUpKit API 的使用应该非常简单直观,因为它是按功能(例如仓库、分支、提交、界面组件等)组织的,并且已尽力清晰地命名函数。
关于“Core”API,学习它们的最佳方式是仔细阅读相关的单元测试——例如,有关分支 API 的内容,请参见 分支测试。
以下是一些帮助您入门的示例代码(错误处理留给读者自行练习):
打开和浏览仓库:
// Open repo
GCRepository* repo = [[GCRepository alloc] initWithExistingLocalRepository:<PATH> error:NULL];
// Make sure repo is clean
assert([repo checkClean:kGCCleanCheckOption_IgnoreUntrackedFiles error:NULL]);
// List all branches
NSArray* branches = [repo listAllBranches:NULL];
NSLog(@"%@", branches);
// Lookup HEAD
GCLocalBranch* headBranch; // This would be nil if the HEAD is detached
GCCommit* headCommit;
[repo lookupHEADCurrentCommit:&headCommit branch:&headBranch error:NULL];
NSLog(@"%@ = %@", headBranch, headCommit);
// Load the *entire* repo history in memory for fast access, including all commits, branches and tags
GCHistory* history = [repo loadHistoryUsingSorting:kGCHistorySorting_ReverseChronological error:NULL];
assert(history);
NSLog(@"%lu commits total", history.allCommits.count);
NSLog(@"%@\n%@", history.rootCommits, history.leafCommits);
修改仓库:
// Take a snapshot of the repo
GCSnapshot* snapshot = [repo takeSnapshot:NULL];
// Create a new branch and check it out
GCLocalBranch* newBranch = [repo createLocalBranchFromCommit:headCommit withName:@"temp" force:NO error:NULL];
NSLog(@"%@", newBranch);
assert([repo checkoutLocalBranch:newBranch options:0 error:NULL]);
// Add a file to the index
[[NSData data] writeToFile:[repo.workingDirectoryPath stringByAppendingPathComponent:@"empty.data"] atomically:YES];
assert([repo addFileToIndex:@"empty.data" error:NULL]);
// Check index status
GCDiff* diff = [repo diffRepositoryIndexWithHEAD:nil options:0 maxInterHunkLines:0 maxContextLines:0 error:NULL];
assert(diff.deltas.count == 1);
NSLog(@"%@", diff);
// Create a commit
GCCommit* newCommit = [repo createCommitFromHEADWithMessage:@"Added file" error:NULL];
assert(newCommit);
NSLog(@"%@", newCommit);
// Restore repo to saved snapshot before topic branch and commit were created
BOOL success = [repo restoreSnapshot:snapshot withOptions:kGCSnapshotOption_IncludeAll reflogMessage:@"Rolled back" didUpdateReferences:NULL error:NULL];
assert(success);
// Make sure topic branch is gone
assert([repo findLocalBranchWithName:@"temp" error:NULL] == nil);
// Update workdir and index to match HEAD
assert([repo resetToHEAD:kGCResetMode_Hard error:NULL]);
完整示例 #1:GitDown
GitDown 是一款非常基础的应用,它会提示用户输入仓库信息,并显示该仓库中存储的交互式实时更新列表(在 -[AppDelegate applicationDidFinishLaunching:] 中仅用约 20 行代码实现):
借助 GitUpKit,这款基础应用还能免费获得无限撤销/重做、统一和并排差异比较、文本选择与复制、键盘快捷键等功能。
此源代码还演示了如何使用 GitUpKit 的其他一些视图控制器,以及如何构建自定义的视图控制器。
完整示例 #2:GitDiff
GitDiff 演示了如何创建一个视图控制器,以 git diff HEAD 的风格显示 HEAD 与工作区之间的实时更新差异:
完整示例 #3:GitY
GitY 是一个 GitX 克隆版,使用 GitUpKit 构建,代码量不到 200 行:
完整示例 #4:iGit
iGit 是一个测试性 iOS 应用,它仅使用 GitUpKit 来克隆 GitHub 仓库并执行提交操作。
贡献
详见 CONTRIBUTING.md。
致谢
同时,非常感谢 libgit2 的优秀贡献者们,没有他们,GitUp 就不可能存在!
许可协议
GitUp 版权所有 2015-2018 Pierre-Olivier Latour,基于 GPL v3 许可协议 发布。有关更多信息,请参阅项目中的 LICENSE 文件。
重要提示: GitUp 包含一些其他开源项目,这些项目仍遵循其各自的许可协议。