1. 初始化仓库
1.1 使用路径打开存在的仓库
repo = Rugged::Repository.new('path/to/my/repository')
1.2 创建一个新的仓库
Rugged::Repository.init_at('.', :bare)
1.3 根据子目录搜寻仓库
Rugged::Repository.discover("/Users/me/projects/repo/lib/subdir/")
2. 分支操作
2.1 创建分支
repo.create_branch('branch-name')
2.2 切换到某一个分支
repo.checkout('branch-name')
2.3 查找分支
根据某个关键字查找分支:
branch_names = []
last_commits = []
repo.branches.each do |branch|
keywords.each do |keyword|
if branch.name.include?(keyword)
branch_names << branch.name
last_commits << repo.branches[branch.name].target
end
end
end
branch_names
用来保存符合条件的分支名字,last_commits
用来保存这些分支的最后一次提交。
2.4 获取分支
branch = repo.branches[branch_name]
3. 增加对文件的追踪
3.1 增加对单个文件的追踪
repo.index.add('./b.txt') # path or object
commit_tree = repo.index.write_tree repo
repo.index.write
相当于 git add b.txt
的操作。注意:index.write 操作会同步暂存区和工作目录。在增加或者删除对文件的追踪后必须要执行,否则执行 git status
看不到预期的效果。疑问:commit_tree = repo.index.write_tree repo
的作用是获取提交时所需要的 tree
参数?
3.2 增加对多个文件的追踪
repo.index.add_all
repo.index.write
相当于 git add -A
操作。
4. 创建 commit
author = { email: "wuzhiyu@note4code.com",
name: "wuzhiyu",
time: Time.now }
options = {}
options[:author] = author
options[:commiter] = author
options[:message] = "commit message here"
options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
options[:tree] = commit_tree
options[:update_ref] = 'HEAD'
Rugged::Commit.create(repo, options)
5. 分支的合并
5.1 commit 合并分析
repo.merge_analysis(last_commits[index])
返回一个包含如下 symbol 组合的数组:
symbol | description |
---|---|
:normal | A “normal” merge is possible, both HEAD and the given commit have diverged from their common ancestor. The divergent commits must be merged. |
:up_to_date | The given commit is reachable from HEAD, meaning HEAD is up-to-date and no merge needs to be performed. |
:fastforward | The given commit is a fast-forward from HEAD and no merge needs to be performed. HEAD can simply be set to the given commit. |
:unborn | The HEAD of the current repository is “unborn” and does not point to a valid commit. No merge can be performed, but the caller may wish to simply set HEAD to the given commit. |
5.2 commit 的合并
#git fetch:
remote = Rugged::Remote.lookup(repo, "origin")
remote.connect(:fetch) do |r|
r.download
r.update_tips!
end
#git merge:
merge_index = repo.merge_commits(
Rugged::Branches.lookup(repo, "master").tip,
Rugged::Branches.lookup(repo, "origin/master").tip
)
raise "Conflict detected!" if merge_index.conflicts?
merge_commit = Rugged::Commit.create(repo, {
parents: [
Rugged::Branches.lookup(repo, "master").tip,
Rugged::Branches.lookup(repo, "origin/master").tip
],
tree: merge_index.write_tree(repo),
message: 'Merged `origin/master` into `master`',
author: { name: "User", email: "example@test.com" },
committer: { name: "User", email: "example@test.com" },
update_ref: 'master'
})
上文中使用了 merge_index.conflicts? 来测试是否有冲突。但是这种冲突检测方法仅限于检测目录的冲突,也就是说只要两个分支修改了同一个文件就会报冲突,但实际上修改的内容可能并不冲突。而使用合并命令则可以针对行来检测是否冲突。