Lesson Three: Using GitHub to Collaborate
- Get practice using GitHub to share your code and collaborate on multi-developer projects.
- Learn how to make and review a pull request on GitHub.
- Get practice by collaborating with other Udacity students to write a create-your-own-adventure story.
课程三主要介绍了 GitHub 的若干操作,包括创建 Repository 、pull、fork、push、pull request。
GitHub Repository 的创建
GitHub 是一个开源项目的 Git Repository 网站,它的 Repository 托管在 GitHub 的服务器上,其 Working Directory 和 Staging Area 无法访问,所以需要在本地 commit 后再上传到 GitHub Repository ,其流程如下:
Local | Local | Local | Remote |
---|---|---|---|
Working Directory | Staging Area | Repository | GitHub Repository |
Files | git add | git commit | git push |
因此 GitHub Repository 也被称为 Remote Repository,简称 Remote,它可以接收本地 push 的 commits,也可以相应 pull,向本地发送 commits。而且将本地 commits 上传到 GitHub 通常是指定一条分支,这样就是实现了多条 commits(可访问 (Reachable) 的)的一次性推送,而无需逐条 push。
通过前面的课程已知使用 git clone 指令可以将 GitHub 上已有的项目下载到本地,而将本地的项目上传到 GitHub 的操作如下:
- 在 GitHub 手动创建一个 Repository,输入代码库名称,不勾选 Initialize this repository with a README(因为勾选会自动生成一个 commit,没有 commit 的 Remote Repository 无法在本地使用 git clone 指令)
- 在本地 Git Bash 或 Terminal 输入指令
# 查看到当前无 Remote Repository
git remote
# 添加一个 Remote Repository,URL 可在 GitHub 找到(在本地使用 git clone 指令会自动设置 origin Remote)
# 这条指令会要求输入 GitHub 的账号密码,针对 Git for Windwos,可以在 Git Bash 中输入
# git config --global credential.helper wincred 缓存账号密码,免除每次输入账号密码的麻烦
git remote add origin url
# 查看到有一个 Remote Repository,名称为 origin
git remote
# 查看 Remote Repository 的详细信息,包括 fetch 和 push 地址,通常为相同的 URL
git remote -v
# 将本地的 master commits push 到 origin Remote 上,Remote 的 branch 也为 master
git push origin master
在浏览器刷新 GitHub Repository 的页面,可以看到本地上传的文件和 commits 记录。
GitHub Pull
当与人协作项目时,或者直接在 GitHub 页面编辑文件后,需要从 Remote 更新 commits 到本地,就要用到 git pull 指令,保持本地分支最新状态。
# 将 origin Remote 的可访问 commits 拉取到本地,同时本地 branch checkout 到最新
git pull origin master
# 查看到 Remote 的 commits
git log
与 git push 类似,在本地也可以看到 Remote 的最新文件和更改记录。
当前已介绍概念的关系图如下。
Git 概念导图GitHub Fork
当需要参与别人的已有项目时,GitHub 可以直接把别人的 Remote fork 到自己账户的 Remote 上,无需 pull 到本地再 push 到自己的 Remote 上。fork 可以理解为 GitHub 服务器端 Repository 的 git clone。fork 有数量记录,也有原始 Repository 的链接,方便对原 Repository 的贡献。
解决协作冲突的示意图当 Local 和 Remote 同时有修改时,此时 push 或 pull 会产生协作冲突,类似 merge conflict。例如上图所示,本地作了 commit a72 的修改,但尚未 push 到 Remote,而 Remote 已有 commit 5b3 的变更,此时 push 或 pull 就会产生冲突。
要解决这种冲突,首先要引入一个新概念:Local Copies of Remote Commits(Remote 在本地的 commits 副本)。继续看上图的例子,当本地作了 commit a72 的修改,但尚未 push 到 Remote,所以此时 Remote 的 commits 副本 origin/master 并不是 Remote 已有 commit 5b3 的变更的最新状态。
因此,要解决 Local commit a72 与 Remote commit 5b3 之间的协作冲突,就要先把 origin/master 的 commits 副本更新到 commit 5b3,这里用到 git fetch 指令更新 origin/master 的 commits 副本,解决冲突后 push 到 Remote。
# 更新 origin/master 的 commits 副本
git fetch origin
# merge 副本和本地的最新 commits,会产生冲突
git merge master origin/master
git add file_conflict
git commit
# 解决冲突后 push 回 Remote
git push origin master
# 查看到本地 branch 与 Remote 的状态为 up to date
git status
从上述介绍可以发现,事实上 git pull origin master
指令相当于 git fetch origin
和 git merge master origin/master
两条指令。在无冲突的情况下即可无需人为参与 merge 操作,GitHub 自动完成。严格来说,Git 会检测 merge 的 Local commit 和 Remote commit 是否存在祖辈关系(可访问的),若有则会触发无需人为参与的 fast-forward merge(快进合并)。
GitHub Pull Request
在与他人协作自己的项目时(在 GitHub Repository 的 settings → collaborators 输入用户名设置协作人),通常的做法是将本地的变更创建一个 branch 并 push 到 Remote,在 GitHub 用 pull request 让协作人审阅变更,或获取反馈;同时不破坏 master,在大家沟通讨论后决定是否将 branch 合并到 master,其实 pull request 是 merge 的概念。具体的操作范例如下:
# 创建一个分支
git branch branch_change
# 切换到分支,并作变更
git checkout branch_change
git add file_change
git commit
# push 到 Remote 的 branch_change 分支
git push origin branch_change
在 GitHub Repository 点击切换到 branch_change 分支(相当于 checkout),点击 pull request,默认的请求地址是原 fork 的 Repository(如果自己的项目是 fork 过来的),这里需要更改为自己的 master,填写相关信息后,点击 create pull request 即成功发送 pull request 请求。
如果在发送 pull request 后 master 有变更,还可以 merge master branch_change 更新 pull request 。
# 切换到 branch_change 分支
git checkout branch_change
# 将 master 合并到 branch_change,并解决冲突
git merge master branch_change
git add file_conflict
git commit
# 将解决方案 push 到 branch_change 分支
git push origin branch_change
最终确认无误后,点击 Merge 即完成一次由分支产生的 merge commit,此时可以删除 branch_change(仅删除 GitHub 的分支,本地的在 pull 后会提示找不到该分支)。
如果是参与别人的项目,想要对原项目作贡献,一般在 fork 后也是创建一个分支进行修改,等适当的时机 pull request 到原 fork 地址,让原作者审阅是否 merge 到 master 上。这样就要求除了在 git clone 时自动生成的 origin Remote 之外,还要手动添加一个原 fork 的 upstream Remote,指令为 git remote add upstream URL
,URL 为原 fork 的 GitHub 地址。pull request 的操作与自己项目的类似,在 GitHub Repository 点击切换到自己的分支,点击 pull request,保持默认原 fork 的请求地址,填写相关信息后,点击 create pull request 即成功发送 pull request 请求,期间等待或与原作者沟通。
其他 Git 指令:
# 以管理员身份启动,支持长目录地址
git config --system core.longpaths true
当前已介绍的所有概念关系图如下。
Git 概念导图
网友评论